Approach 1:
Generate all "combinations" of m+n
elements taken from the set [0 1]
. This can be done efficiently using this approach.
Keep only those combinations that contain n
ones.
Code:
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,:);
Example result for 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
Approach 1 modified
To save memory, use uint8
values in step 1, and convert to double
at the end of step 2:
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,:));
Approach 2:
Similar to approach 1, but in step 1 generate all combinations as binary expressions of all integers from 0
to 2^(m+n)-1
, using dec2bin
. This produces a char
array, so it should be as memory-efficient as approach 1 modified. Then, step 2 should be slightly adapted to use char
s, and a final conversion to numeric values is required:
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';