2016-12-06 19 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