2016-12-06 25 views
1

我有一個問題,在100x100的網格上有4個對象(1s)被分成16個均勻的25x25的正方形。 enter image description here 我需要創建一個(16^4 * 4)表,其中條目列出了16個子表中這4個對象中每個對象的所有可能位置。只要不相互重疊,對象可以位於子矩陣內的任何位置。這顯然是一個置換問題,但由於索引和位置必須是隨機的,但在16個方格內不重疊的事實會增加複雜性。會愛任何指針!MATLAB - 在網格特定區域隨機指數的排列

我試圖做的是創建一個名爲「top_left_corner(position)」的函數,它返回您所在子矩陣左上角的下標。 top_left_corner(1)=(1,1),top_left_corner(2)=(26,1),等。然後我有:

 pos = randsample(24,2); 
     I = pos(1)+top_left_corner(position,1); 
     J = pos(2)+top_left_corner(position,2); 

的問題是如何生成和的這個商店排列在表中作爲線性指數。

回答

0

首先使用在[4 , 16^4]矩陣perm的形式產生ndgrid笛卡兒積。然後在while循環中生成隨機數並添加到perm中。如果任何perm列包含重複的隨機數,則爲這些列重複隨機數生成,直到沒有列具有重複的元素爲止。通常不需要超過2-3次迭代。由於[100,100]陣列被分成16個塊,因此使用kron索引模式(如生成的16個塊)和提取的已排序元素的函數索引。然後生成的隨機數形成模式的索引(16個塊)。

C = cell(1,4); 
[C{:}]=ndgrid(0:15,0:15,0:15,0:15); 
perm = reshape([C{:}],16^4,4).'; 

perm_rnd = zeros(size(perm)); 
c = 1:size(perm,2); 
while true 
    perm_rnd(:,c) = perm(:,c) * 625 +randi(625,4,numel(c)); 
    [~ ,c0] = find(diff(sort(perm_rnd(:,c),1),1,1)==0); 
    if isempty(c0) 
     break; 
    end 
    %c = c(unique(c0)); 
    c = c([true ; diff(c0)~=0]); 
end 
pattern = kron(reshape(1:16,4,4),ones(25)); 

[~,idx] = sort(pattern(:)); 
result = idx(perm_rnd).'; 
+0

哇!謝謝,這絕對是真棒。真的很感謝:) –

+0

我可能會補充說我最終做了一些與「perm_rnd」不同的事情,因爲它並沒有完全取得我需要的排列。 'range = 0:15; 組合= permn(範圍,4); perms =轉置(組合); perm_rnd =零(大小(perms));' 這是使用permn函數,可以發現[這裏](https://www.mathworks.com/matlabcentral/fileexchange/7147-permn-v--n--k-) –

+0

沒有區別。由於numel(0:15)> 4,所以都生成笛卡爾積 – rahnema1