如何找到'A = nchoosek(1:m,n)`的行`i`

时间:2015-04-20 10:18:20

标签: matlab

对于给定的A (i,:)A= nchoosek(1:m,n)i,我想找到m,其中n。 MATLAB的这个命令耗费时间和内存,特别适用于大m。所以,我不想构建整个A。我想只构建i的行A

虽然我的问题似乎与“Combinations from a given set without repetition”重复,但它们不同。它只为A = nchoosek(1:m,2)提供了可接受的结果,并且不包括两列以上。

1 个答案:

答案 0 :(得分:2)

我找到了similar question on SO并在MATLAB中实现了提议的解决方案:

function [result] = kth_combination(k,l,r)

if r == 0
    result = [];
elseif size(l,2) == r
    result = l;
else
    i = nchoosek(size(l,2)-1,r-1);
    if k < i+1
        result = [l(1), kth_combination(k, l(2:end), r-1)];
    else
        result = kth_combination(k-i, l(2:end), r);
    end
end
end

MATLAB File Exchange上还有另一种解决方案,它不基于递归:onecomb

为了比较3个解决方案,我创建了这个基准函数:

function [time_1,time_2, time_3] = compare_solutions(m,n,i,num_runs)
time_1 = 0;
time_2 = 0;
time_3 = 0;

for run=1:num_runs

    tic
    A=nchoosek(1:m,n);
    res_1 = A(i,:);
    time_1 = time_1 + toc;

    tic
    res_2 = kth_combination(i,1:m,n);
    time_2 = time_2 + toc;

    tic 
    res_3 = onecomb(m,n,i);
    time_3 = time_3 + toc;

    if (run==1) && (sum(res_1 ~= res_2) || sum(res_1 ~= res_3))
        error('solutions are NOT identical');
    end

end

time_1 = time_1/num_runs;
time_2 = time_2/num_runs;
time_3 = time_3/num_runs;

end

示例运行:

>>  [time_1,time_2, time_3]  = compare_solutions(20,10,10,10)

time_1 =

    1.9676

time_2 =

    6.8508e-04

time_3 = 

    7.1848e-05

第二和第三种解决方案比nchoosek方法更快,与递归方法相比,非递归方法甚至更快10倍。