It might not be the most beautiful algorithm in the world, but this works (on 64 bit MATLAB) for even N values up to at least
- N = 20, giving 184756 rows in 15 seconds
- N = 22, giving 705432 rows in 106 seconds.
- N = higher might be possible, if you are patient enough and have enough memory...
but keep in mind that at some point you will simply run out of memory.
It is easy to check that all rows sum to the requested value. In contrast there is no obvious way to check if any rows are missing, but I did notice that the number of rows matches exactly with OEIS A000984, which might have some relevance. N = 12;
M = [0,1;1,0];
for k = 3:N
R = size(M,1);
M = [zeros(R,1),M;ones(R,1),M;M,zeros(R,1);M,ones(R,1)];
M = unique(M(sum(M,2)<=N/2,:),'rows');
end
M = M(sum(M,2)==N/2,:);
For N=12 this gives:
>> size(M)
ans =
924 12
>> M
ans =
0 0 0 0 0 0 1 1 1 1 1 1
0 0 0 0 0 1 0 1 1 1 1 1
0 0 0 0 0 1 1 0 1 1 1 1
0 0 0 0 0 1 1 1 0 1 1 1
0 0 0 0 0 1 1 1 1 0 1 1
0 0 0 0 0 1 1 1 1 1 0 1
0 0 0 0 0 1 1 1 1 1 1 0
0 0 0 0 1 0 0 1 1 1 1 1
0 0 0 0 1 0 1 0 1 1 1 1
...
1 1 1 1 0 1 0 0 1 0 0 0
1 1 1 1 0 1 0 1 0 0 0 0
1 1 1 1 0 1 1 0 0 0 0 0
1 1 1 1 1 0 0 0 0 0 0 1
1 1 1 1 1 0 0 0 0 0 1 0
1 1 1 1 1 0 0 0 0 1 0 0
1 1 1 1 1 0 0 0 1 0 0 0
1 1 1 1 1 0 0 1 0 0 0 0
1 1 1 1 1 0 1 0 0 0 0 0
1 1 1 1 1 1 0 0 0 0 0 0
PS: of course recursive algorithms for generating permutations are simple but when I tried some with added short-circuit behavior for repeated rows, they were significantly slower than the above loop.
Best Answer