给定元素集的唯一(有限长度)组合 - 在Matlab中实现

时间:2014-11-21 12:52:10

标签: matlab combinations

我有以下问题。我需要重现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,这实在是非常耗时。任何人都可以想一个更有效的解决方案?

1 个答案:

答案 0 :(得分:3)

方法1

  1. 生成所有"组合"取自m+n集的[0 1]个元素。这可以使用this approach高效完成。

  2. 仅保留包含n个组合的组合。

  3. 代码:

    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将所有组合生成为02^(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';