我有以下问题。我需要重现0和1的所有独特组合,包括正好m个零和正好n个。例如,如果我有2个零和3个,我正在寻找的组合是以下10个:
1)0 0 1 1 1
2)0 1 0 1 1
3)0 1 1 0 1
4)0 1 1 1 0
5)1 0 0 1 1
6)1 0 1 0 1
7)1 0 1 1 0
8)1 1 0 0 1
9)1 1 0 1 0
10)1 1 1 0 0
现在,我正在使用A = perms([0 0 1 1 1])然后使用唯一(A,'rows')但如果向量的长度超过10,这实在是非常耗时。任何人都可以想一个更有效的解决方案?
答案 0 :(得分:3)
方法1 :
生成所有"组合"取自m+n
集的[0 1]
个元素。这可以使用this approach高效完成。
仅保留包含n
个组合的组合。
代码:
m = 7; %// number of zeros
n = 9; %// number of ones
L = m+n;
vectors = repmat({[0 1]}, 1, L);
combs = cell(1,L);
[combs{end:-1:1}] = ndgrid(vectors{end:-1:1});
combs = cat(L+1, combs{:});
combs = reshape(combs,[],L);
combs = combs(sum(combs,2)==n,:);
m=2; n=3
的示例结果:
combs =
0 0 1 1 1
0 1 0 1 1
0 1 1 0 1
0 1 1 1 0
1 0 0 1 1
1 0 1 0 1
1 0 1 1 0
1 1 0 0 1
1 1 0 1 0
1 1 1 0 0
方法1已修改
要节省内存,请在步骤1中使用uint8
值,并在步骤2结束时转换为double
:
m = 7; %// number of zeros
n = 9; %// number of ones
L = m+n;
vectors = repmat({uint8([0 1])}, 1, L);
combs = cell(1,L);
[combs{end:-1:1}] = ndgrid(vectors{end:-1:1});
combs = cat(L+1, combs{:});
combs = reshape(combs,[],L);
combs = double(combs(sum(combs,2)==n,:));
方法2 :
与方法1类似,但在步骤1中,使用dec2bin
将所有组合生成为0
到2^(m+n)-1
的所有整数的二进制表达式。这会生成一个char
数组,因此它应该像修改方法1一样具有内存效率。然后,步骤2应略微适应使用char
s,并且最终需要转换为数值:
m = 7; %// number of zeros
n = 9; %// number of ones
combs = dec2bin(0:2^(m+n)-1);
combs = combs(sum(combs=='1',2)==n,:)-'0';