给定元素集的唯一(有限长度)组合 - Matlab 中的实现
Posted
技术标签:
【中文标题】给定元素集的唯一(有限长度)组合 - Matlab 中的实现【英文标题】:Unique (finite length) combinations of a given set of elements - Implementation in Matlab 【发布时间】:2015-01-19 15:05:04 【问题描述】:我有以下问题。我需要重现 0 和 1 的所有独特组合,其中包括正好 m 个零和正好 n 个。例如,如果我有 2 个 0 和 3 个 1,我正在寻找的组合是以下 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]) 然后 unique(A,'rows') 但是如果向量的长度超过 10,这真的很耗时。任何人都可以想出更有效的解决方案?
【问题讨论】:
【参考方案1】:方法一:
从集合[0 1]
中生成m+n
元素的所有“组合”。这可以使用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);
[combsend:-1:1] = ndgrid(vectorsend:-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);
[combsend:-1:1] = ndgrid(vectorsend:-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';
【讨论】:
以上是关于给定元素集的唯一(有限长度)组合 - Matlab 中的实现的主要内容,如果未能解决你的问题,请参考以下文章