我有以下矩阵:
1 1 1 1 1 1 1 1 1 1 1 1 2 2 2 2 2 2 2 2 2 2 2 2
0 0 1 2 0 0 1 2 0 0 1 2 0 0 1 2 0 0 1 2 0 0 1 2
0 0 0 0 1 1 1 1 2 2 2 2 0 0 0 0 1 1 1 1 2 2 2 2
我想随机排列列,限制条件是第二行中的每四个数字应包含某种形式的
0 0 1 2
例如下面示例中的 1:4、5:8、9:12、13:16、17:20、21:24 列各包含数字 0 0 1 2。
0 1 0 2 2 0 1 0 0 0 2 1 1 2 0 0 2 0 1 0 1 0 0 2
置换矩阵中的每一列都应在第一个矩阵中具有对应的列。换句话说,列中不应更改任何内容。
我似乎想不出一个直观的解决方案 - 是否有另一种方法可以提出某种形式的初始矩阵,既满足约束又保留列的完整性?每列代表实验中的条件,这就是为什么我希望它们保持平衡。
最佳答案
您可以通过以下方式直接计算排列:首先,将第二行中带有 0
的所有列相互排列,然后将所有 1
相互排列,然后最后所有 2
彼此之间。例如,这可以确保任意两个 0
列同样可能是 A
的结果排列中的前两列。
第二步是排列 4 block 中的所有列:随机排列 1-4 列,随机排列 5-8 列,等等。完成此操作后,您将拥有一个矩阵,该矩阵为每个列维护 (0 0 1 2) 模式4 列的 block ,但每组 (0 0 1 2) 同等可能出现在任何给定的 4 列 block 中,并且 (0 0 1 2) 同等可能处于任何顺序。
A = [1 1 1 1 1 1 1 1 1 1 1 1 2 2 2 2 2 2 2 2 2 2 2 2
0 0 1 2 0 0 1 2 0 0 1 2 0 0 1 2 0 0 1 2 0 0 1 2
0 0 0 0 1 1 1 1 2 2 2 2 0 0 0 0 1 1 1 1 2 2 2 2];
%% Find the indices of the zeros and generate a random permutation with that size
zeroes = find(A(2,:)==0);
perm0 = zeroes(randperm(length(zeroes)));
%% Find the indices of the ones and generate a random permutation with that size
wons = find(A(2,:) == 1);
perm1 = wons(randperm(length(wons)));
%% NOTE: the spelling of `zeroes` and `wons` is to prevent overwriting
%% the MATLAB builtin functions `zeros` and `ones`
%% Find the indices of the twos and generate a random permutation with that size
twos = find(A(2,:) == 2);
perm2 = twos(randperm(length(twos)));
%% permute the zeros among themselves, the ones among themselves and the twos among themselves
A(:,zeroes) = A(:,perm0);
A(:,wons) = A(:,perm1);
A(:,twos) = A(:,perm2);
%% finally, permute each block of 4 columns, so that the (0 0 1 2) pattern is preserved, but each column still has an
%% equi-probable chance of being in any position
for i = 1:size(A,2)/4
perm = randperm(4) + 4*i-4;
A(:, 4*i-3:4*i) = A(:,perm);
end
结果示例:
A =
Columns 1 through 15
1 1 2 2 2 2 1 1 2 2 1 2 2 1 2
0 0 2 1 0 2 0 1 0 2 1 0 1 2 0
0 1 2 2 2 0 1 1 1 1 2 0 0 2 0
Columns 16 through 24
2 1 1 1 1 1 2 2 1
0 2 0 0 1 0 0 1 2
1 1 2 2 0 0 2 1 0
在运行 MATLAB 2016a 时,我能够在大约 9.32 秒内生成 100000 个 A
的约束排列,让您了解此代码需要多长时间。当然有一些方法可以优化排列选择,这样您就不必进行如此多的随机抽取,但我总是更喜欢简单、直接的方法,直到它被证明是不够的。
关于arrays - 带约束的矩阵排列,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37845844/