arrays - 带约束的矩阵排列

标签 arrays matlab matrix permutation

我有以下矩阵:

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/

相关文章:

c - 数组变量的 "value"是什么?

Matlab类方法错误

matlab - 如何在没有 for 循环的情况下在 matlab 中将矩阵提升为幂向量?

python:二维矩阵中更快的局部最大值

从 R 中的矩阵中删除行名列表

mysql - 从查询中获取并回显 mysql 数组

python - numpy.repeat 的反义词是什么?

javascript - 查找数组中是否有两个或多个键

matlab - 16-QAM 调制和解调 - 图中缺少一条线

将 R 代码转换为 C 代码