3

以下の MATLAB コードでは、要素 ( ) の一部を6でランダムに置き換えることにより、行列Bが行列Aから作成されます。マトリックス全体で要素の値をランダムに置き換える代わりに、どうすればそれらを束ねたままにできますか (ただし、束の配置はランダムです)? empty_xempty_x

つまり、すべての6値要素を隣接させたいということです。正方行列Aempty_xの要素をより小さなサブセット化された正方行列 (サイズ)に置き換えて行列Bを作成するのが最も簡単な場合は、それで問題ありません。常に正方行列であるとは限らない (つまり、不均一性) 塊があると便利ですが、必須ではありません。 empty_x

このタスクを達成する方法についていくつかのアイデアをいただければ幸いです。

乾杯。

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

毎回 1 つの乱数を生成しても、それほど遅くはなりません。それが本当にボトルネックである場合、それを高速化する方法も間違いなくあります。うまくいけば、この例があなたをもう少し先に進めることができます.

于 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 に答える