您可以在matlab中的给定顺序的每个矩阵中生成固定数量为1的所有可能的二元矩阵。
例如,所有4x4矩阵,每个矩阵中有两个1, [1 1 0 0; 0 0 0 0; 0 0 0 0; 0 0 0 0],[1 0 0 0; 0 1 0 0; 0 0 0 0; 0 0 0 0],[1 0 0 0; 0 0 0 0; 1 0 0 0; 0 0 0 0]
答案 0 :(得分:2)
这是一个矢量化解决方案:
N = 4; % matrix size
M = 2; % number of ones
ind = nchoosek(1:N^2, M);
result = zeros(N,N,size(ind,1));
result(bsxfun(@plus, ind, (0:size(ind,1)-1).'*N^2)) = 1;
每个矩阵都是result
的第三个切片:
>> result
result(:,:,1) =
1 0 0 0
1 0 0 0
0 0 0 0
0 0 0 0
result(:,:,2) =
1 0 0 0
0 0 0 0
1 0 0 0
0 0 0 0
···
result(:,:,120) =
0 0 0 0
0 0 0 0
0 0 0 1
0 0 0 1
答案 1 :(得分:0)
如果你想创造每个组合应该有(16x15)/ 2组合(Matsize * Matsize-1)/ 2),因为你可以在任何地方选择拳头,第二个在任何地方,但第一个和第二个由2表示1-2与2-1相同。请注意,如果您想要3' 1'例如,你必须有16x15x14 / 6(作为3 facotrial)。有一个MATLAB函数可以获得每个组合,然后您只需创建每个矩阵,同时使用组合作为索引(在4x4矩阵中,您可以将矩阵(2,1)作为矩阵(5))。
C = combnk(1:16,2); %16 elements and 2 '1'
Matrizes = zeros(length(C),4,4);
for i=1:size(Matrizes,1)
Matrizes(i,C(i,:))=1;
end
肯定有一种摆脱for循环的方法,但是因为我不知道这对于性能如何关键,所以我只是采取了简单的方法。
答案 2 :(得分:0)
您可以找到长度为2的所有索引子集,然后在该索引中替换1
s。首先使用following code找到具有指定长度的子集:
function subsets = get_subset(N, c)
indices = dec2bin(1:(2 ^ N - 1)) - '0'; % indices of all subsets
counter = sum(indices, 2); % number of elements in subsets
subsets = indices(find(counter == c), :); % select appropriate subsets
end
然后,获取所有可能的索引并替换1
s:
n = 10; k = 2;
A = zeros(n);
all = cell(1,nchoosek(n,k));
subsets = get_subset(numel(A), k);
len = size(subsets,1);
for i = 1:len
temp = A;
temp(find(subsets(i,:) == 1)) = 1;
all{i} = temp;
end
<强>更新强>
为了提高效率,您可以使用get_subset
作为matlab中的本机函数,而不是combnk
。
n = 10; k = 2;
A = zeros(n);
all = cell(1,nchoosek(n,k));
subsets = combnk(numel(A), k);
len = size(subsets,1);
for i = 1:len
temp = A;
temp(find(subsets(i,:) == 1)) = 1;
all{i} = temp;
end