3

在下面的 MATLAB 代码中,矩阵B是通过将矩阵A的一部分元素 ( empty_x)随机替换为6来创建的。不是在empty_x整个矩阵中随机替换元素的值,而是如何使它们保持聚集(但仍然随机放置簇)?

那就是我希望所有6值元素都是相邻的。如果用更小的、子集化的方阵 (size ) 替换empty_x方阵Aempty_x中的元素来创建矩阵B是最简单的,那么就可以了。拥有并不总是方阵(即异质性)的团块会很酷,但不是必须的。

我将不胜感激有关如何完成此任务的一些想法。

干杯。

A = [1 2 3 4 5; 5 4 3 2 1; 1 4 3 2 5; 4 3 2 1 5; 2 1 3 5 4];
B = A;
nA = numel(A);
empty_x = randi(10);
B(randperm(nA,(empty_x))) = 6;
4

2 回答 2

1

我的方法如下:

1) Generate a single random number (uniform distribution)  
     on the interval `[1 numel(A)]`. Use this as the linear index  
     of a seed for your clump.  

while clump_size < desired_clump_size     
    2) Generate a list of all positions in the matrix adjacent to  
         (but not already included in) the existing clump.  
    3) Randomly select one of these indices  
    4) Grow the clump by placing an element in this position.  
end 

我不打算写代码;实现起来应该不难,特别是如果这段代码不是整个项目的性能瓶颈。

编辑:既然你自己试了一下,这里有一些代码:

desired_clump = 5;
matrix_size = 5;
A = zeros(matrix_size);
[C,R]=meshgrid(1:size(A,1), (1:size(A,2))'); %'# row and column numbers for each element

seed = ceil(rand(1)*numel(A));
#% I would have used randi(1) but octave online utility doesn't have it
A(seed) = 1; #% initialize a clump
clump_size = 1;

while clump_size < desired_clump
    CI = A==1; #% logical index of current clump
    CR = reshape(R(CI),1,1,[]); #% 1x1xN index of row values of current clump
    CC = reshape(C(CI),1,1,[]); #% 1x1xN index of col values of current clump
    ADJ = sum(bsxfun(@(x,y)abs(x-y),R,CR)<=1 & bsxfun(@(x,y)abs(x-y),C,CC)<=1, 3)>0 & ~A;
    #% ADJ is the indices of the elements adjacent to the current clump
    B=A; #% for display purposes only
    B(ADJ)=2;
    disp(B)
    disp(' ')
    POS = find(ADJ); #% linear indices of the adjacent elements
    IND = ceil(rand(1)*numel(POS)); #% random index into POS vector
    A(POS(IND))=1; #% grow the clump
    clump_size = clump_size+1;
end
disp(A);

输出: 1表示丛中的元素;2意味着有资格进行丛集扩展

iteration 1:
   0   0   2   1   2
   0   0   2   2   2
   0   0   0   0   0
   0   0   0   0   0
   0   0   0   0   0
iteration 2: 
   0   0   2   1   2
   0   0   2   1   2
   0   0   2   2   2
   0   0   0   0   0
   0   0   0   0   0
iteration 3: 
   0   0   2   1   2
   0   0   2   1   2
   0   0   2   1   2
   0   0   2   2   2
   0   0   0   0   0
iteration 4: 
   0   0   2   1   1
   0   0   2   1   2
   0   0   2   1   2
   0   0   2   2   2
   0   0   0   0   0

Final clump:
   0   0   0   1   1
   0   0   1   1   0
   0   0   0   1   0
   0   0   0   0   0
   0   0   0   0   0

每次生成一个随机数不应该那么慢。如果它确实是一个瓶颈,毫无疑问还有一些方法可以加速它。希望这个例子能让你更进一步。

于 2012-12-01T05:54:06.447 回答
0

使用上面的一些技巧,我构建了下面的代码。它适用于较小尺寸的A,但当A很大时它非常慢。感谢您的指导。

clear all
A = zeros(40,40);
[M N] = size(A);
B = A;
nA = numel(A);
per_clump = 10;
dClump = nA*(per_clump/100);
seed = randi(nA);
clumpers = zeros(8,1);
new_seed = seed;
counter = 0;
while counter < dClump; % size of clump
    seed = new_seed;

    for iSize = seed; % find adjacent elements

        west = iSize - M;
        if west < 1
            west = iSize; % the boundary is not periodic
        end;

        east = iSize + M;
        if east > nA
            east = iSize;
        end; %

        north = iSize - 1;
        if north < 1
            north = iSize;
        end; %

        south = iSize + 1;
        if south > nA
            south = iSize;
        end; %

        nwest = iSize - M - 1;
        if nwest < 1
            nwest = iSize;
        end; %

        neast = iSize + M - 1;
        if neast > nA
            neast = iSize;
        end; %

        swest = iSize - M + 1;
        if swest < 1
            swest = iSize;
        end; %

        seast = iSize + M + 1;
        if seast > nA
            seast = iSize;
        end; %

        clumpers = [(west) (east) (north) (south) (nwest) (neast) (seast) (swest)]; % index of adjacent elements
        %new_seed = randsample(clumpers,1); % pick one, really slow

        z = randperm(size(clumpers,2)); % this also really slow
        new_clumpers = clumpers(z);
        new_seed = new_clumpers(randi(8));

        if B(new_seed) == 6;
            %B(new_seed) = B(seed);
            new_seed = seed;
            counter = counter;
        else
            B(new_seed) = 6;
            counter = counter+1;
        end;
    end; %end adj element
end; % end clump size
于 2012-12-02T01:51:25.560 回答