为大 X 查找具有 n 个非零数字的 X 二进制数。 - Matlab

Finding X binary numbers with n non-zero digits for large X. - Matlab

是否有更有效的方法来生成范围为 1 到 N 的 X 个二进制数(具有 n 个非零数字)?我制定了以下解决方案:

Totalcombos = nchoosek(N,n);                             
floor = floor(log2(Totalcombos));
L = 2.^floor;    
NumElem = 2^N-1;
i=0;
x=1;
%Creates Index combination LUT 
while 1
    %Produces Binary from 1 : NumElem
    binNum= de2bi(x,N,'right-msb')';
    x=x+1;
    %Finds number of bits in each binary number
    NumOfBits = sum(binNum);    
    %Creates a matrix of binary numbers from 1:NumElem with n 1's
    if NumOfBits == n
        i=i+1;
        ISmatrixShapes{i} = binNum(:,:);
    end
    if i==L
        break
    end
end
ISmatrixShape2=cell2mat(ISmatrixShapes);
ISmatrixShape=ISmatrixShape2(:,1:L)';

有没有一种方法可以在不进行大量循环迭代的情况下生成这些值?

这会生成所有 N 位二进制数,其中包含 n 个 1 和 N-n 个零:

N = 5;
n = 3;
ind = nchoosek(1:N, n);
S = size(ind,1);
result = zeros(S,N);
result(bsxfun(@plus, (ind-1)*S, (1:S).')) = 1;

它的工作原理是从 N 个可能位置(nchoosek 行)中生成 n 个位置的所有组合,然后用 1 填充这些值使用线性索引(bsxfun 行)。

本例中的结果是

result =
     1     1     1     0     0
     1     1     0     1     0
     1     1     0     0     1
     1     0     1     1     0
     1     0     1     0     1
     1     0     0     1     1
     0     1     1     1     0
     0     1     1     0     1
     0     1     0     1     1
     0     0     1     1     1

另一种效率较低的方法是生成包含 n 个 1 和 N-n 个零的向量的所有排列,然后删除重复项:

result = unique(perms([ones(1,n) zeros(1,N-n)]), 'rows');