我已经编写了这段代码:
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');
但是我根本不想使用置换,因为我想使用此代码并制作尺寸更大的矩阵,而使用置换使之不可能。
答案 0 :(得分:2)
您将在{1乘8的1个向量中生成-1
的2个值的每个排列。因此,您可以使用nchoosek
生成-1
值的列索引,然后使用sub2ind
在单个索引步骤中修改矩阵a
:
indices = nchoosek(1:8, 2);
N = size(indices, 1);
a = ones(N, 8);
a(sub2ind([N 8], [1:N 1:N].', indices(:))) = -1;
输出:
a =
-1 -1 1 1 1 1 1 1
-1 1 -1 1 1 1 1 1
-1 1 1 -1 1 1 1 1
-1 1 1 1 -1 1 1 1
-1 1 1 1 1 -1 1 1
-1 1 1 1 1 1 -1 1
-1 1 1 1 1 1 1 -1
1 -1 -1 1 1 1 1 1
1 -1 1 -1 1 1 1 1
1 -1 1 1 -1 1 1 1
1 -1 1 1 1 -1 1 1
1 -1 1 1 1 1 -1 1
1 -1 1 1 1 1 1 -1
1 1 -1 -1 1 1 1 1
1 1 -1 1 -1 1 1 1
1 1 -1 1 1 -1 1 1
1 1 -1 1 1 1 -1 1
1 1 -1 1 1 1 1 -1
1 1 1 -1 -1 1 1 1
1 1 1 -1 1 -1 1 1
1 1 1 -1 1 1 -1 1
1 1 1 -1 1 1 1 -1
1 1 1 1 -1 -1 1 1
1 1 1 1 -1 1 -1 1
1 1 1 1 -1 1 1 -1
1 1 1 1 1 -1 -1 1
1 1 1 1 1 -1 1 -1
1 1 1 1 1 1 -1 -1
答案 1 :(得分:2)
@gnovice的答案非常好,但是我想为教学目的添加一个替代答案。正如gnovice所说,“您将在1乘8的1的向量中产生将-1的2个值定位的每个排列”。。我们可以通过考虑如何生成[-1 -1 1 1 1 1 1 1]
的连续排列来解决这个问题。
来自C++
,这非常直观,因为algorithm
库提供了std::next_permutation
,可生成向量的下一个lexicographical排列。该算法非常简单,可以在以下位置找到:https://en.cppreference.com/w/cpp/algorithm/next_permutation。实际上,Jos已在matlab
中实现了该算法的更为通用的版本。我们将使用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