matlab - 如何更有效地制作这个排列矩阵?

标签 matlab matrix permutation

我写了这段代码:

a = repelem(ones(7,8)-2.*eye(7,8), 7:-1:1, 1);
for i=1:7
    a(i,i+1)=-1;
end
for i=8:13
    a(i,i-5)=-1;
end
for i=14:18
    a(i,i-10)=-1;
end
for i=19:22
    a(i,i-14)=-1;
end
for i=23:25
    a(i,i-17)=-1;
end
for i=26:27
    a(i,i-19)=-1;
end
for i=28:28
    a(i,i-20)=-1;
end

生成此矩阵:

-1  -1   1   1   1   1   1   1
-1   1  -1   1   1   1   1   1
-1   1   1  -1   1   1   1   1
-1   1   1   1  -1   1   1   1
-1   1   1   1   1  -1   1   1
-1   1   1   1   1   1  -1   1
-1   1   1   1   1   1   1  -1
 1  -1  -1   1   1   1   1   1
 1  -1   1  -1   1   1   1   1
 1  -1   1   1  -1   1   1   1
 1  -1   1   1   1  -1   1   1
 1  -1   1   1   1   1  -1   1
 1  -1   1   1   1   1   1  -1
 1   1  -1  -1   1   1   1   1
 1   1  -1   1  -1   1   1   1
 1   1  -1   1   1  -1   1   1
 1   1  -1   1   1   1  -1   1
 1   1  -1   1   1   1   1  -1
 1   1   1  -1  -1   1   1   1
 1   1   1  -1   1  -1   1   1
 1   1   1  -1   1   1  -1   1
 1   1   1  -1   1   1   1  -1
 1   1   1   1  -1  -1   1   1
 1   1   1   1  -1   1  -1   1
 1   1   1   1  -1   1   1  -1
 1   1   1   1   1  -1  -1   1
 1   1   1   1   1  -1   1  -1
 1   1   1   1   1   1  -1  -1

我正在寻找一种更有效的方法来生成这个矩阵。一种方法是:

S=[-1 -1 1 1 1 1 1 1];
P=unique(perms(S),'rows');

但我根本不想使用排列,因为我想使用这段代码并制作具有更大维度的矩阵,而使用排列使其不可能。

最佳答案

@gnovice 的答案非常好,但是我想出于教学目的添加替代答案。正如 gnovice 所说,“您正在生成在 1×8 向量中定位 2 个 -1 值的所有排列”。我们可以通过思考如何生成 [-1 -1 1 1 1 1 1 1] 的连续排列来将其应用于我们的问题。

来自C++,这非常直观,因为算法库提供了std::next_permutation,它生成下一个lexicographical你的向量的排列。该算法非常简单,可以在这里找到:https://en.cppreference.com/w/cpp/algorithm/next_permutation 。事实上,Josmatlab 中实现了该算法的更通用版本。 。我们将利用 nextperm_local,它位于 nextperm 文件交换页面“函数”选项卡的最底部。 .

myP = [-1 -1 1 1 1 1 1 1];

function P = nextperm_local(P)
    k1 = find(P(2:end) > P(1:end-1), 1, 'last');
    if isempty(k1)
        k1 = 0;
    else
        k2 = find(P(k1)<P, 1, 'last');
        P([k1 k2]) = P([k2 k1]);
    end
    P((k1+1):end) = P(end:-1:(k1+1));
end

total = nchoosek(8, 2);
output = zeros(total, 8);

for i = 1:total
    output(i,:) = myP ;
    myP = nextperm_local(myP) ;
end

并产生以下矩阵:

output =

  -1  -1   1   1   1   1   1   1
  -1   1  -1   1   1   1   1   1
  -1   1   1  -1   1   1   1   1
  -1   1   1   1  -1   1   1   1
  -1   1   1   1   1  -1   1   1
  -1   1   1   1   1   1  -1   1
  -1   1   1   1   1   1   1  -1
   1  -1  -1   1   1   1   1   1
   1  -1   1  -1   1   1   1   1
   1  -1   1   1  -1   1   1   1
   1  -1   1   1   1  -1   1   1
   1  -1   1   1   1   1  -1   1
   1  -1   1   1   1   1   1  -1
   1   1  -1  -1   1   1   1   1
   1   1  -1   1  -1   1   1   1
   1   1  -1   1   1  -1   1   1
   1   1  -1   1   1   1  -1   1
   1   1  -1   1   1   1   1  -1
   1   1   1  -1  -1   1   1   1
   1   1   1  -1   1  -1   1   1
   1   1   1  -1   1   1  -1   1
   1   1   1  -1   1   1   1  -1
   1   1   1   1  -1  -1   1   1
   1   1   1   1  -1   1  -1   1
   1   1   1   1  -1   1   1  -1
   1   1   1   1   1  -1  -1   1
   1   1   1   1   1  -1   1  -1
   1   1   1   1   1   1  -1  -1

关于matlab - 如何更有效地制作这个排列矩阵?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51551109/

相关文章:

matlab - 查找 MATLAB 矩阵中重复次数最多的行

matlab - 使用matlab求和系列

algorithm - 最小列总和差异是多少?

javascript - 生成完全包含原始集合中元素的子集的所有组合

recursion - 了解 Peter Norvig 在 PAIP 中的置换解决方案

matlab - 如何给出向量中每个元素的顺序

matlab - 在 Matlab 中 : How to keep all xTicks but xTicklabels just on every 6 xTicks?

c - 如何在C中复制矩阵?

r - 如何对Matrix包中的“sparseMatrix”类的对象进行QR分解?

python - Python 的 itertools.combinations() 的 SQL 版本