1

我正在寻找使用线性索引索引 M 选择 N 元组。前段时间我写了 M 选择 2 作为一些配对索引函数的代码:

   function K=pairidx( i, j)
      if(i>j)
        swap(i,j);
      K=j-(i+1) +   (i)*(2*M-1)-i*(i-1)/2;
   end

我现在需要的是将此推广到 M 选择 N。理想情况下,我将有一个可逆函数,我可以将索引 K 转换为某个元组(K_1,K_2,...,K_N)。到目前为止,我一直在做一种蛮力方法,对于 N=3,我编写了以下函数,但我希望这不是最好的方法。

function lookup=tripletable()
d=nchoosek(M,N);
idx=1;
lookup=zeros(d,3);
for i=1:M
     for j=i+1:M
         for k=j+1:M
             lookup(idx,:)=[i,j,k];
             idx=idx+1;
         end
     end
end
4

1 回答 1

0

正如 Jerad 评论的那样,您可以使用nchoosek(v,k)生成整个组合列表,然后让 Matlab 将您的(排序的)组合与任何行匹配。但是,这将需要生成整个列表,如果 M 和 N 变大,这可能会非常大。

您可以使用以下代码按索引获取组合。它计算可能组合的数量并检查您给出的索引是否在该范围内。然后它迭代地继续确定所有元素

function combination=getCombinationByIndex(v,K,N)
M=size(v,2);
k=K;
l=0;
combination=zeros(1,N);
for i=1:N
    %determine combination(i)
    while(true)
        l=l+1;
        C=nchoosek(M-l,N-i);         
        if(k>C)
            k=k-C;
        else
            combination(i) = v(l);
            break;
        end
    end
end

反向操作类似:只需对您的组合进行排序并检查元素,检查您当前的组合是否在该范围内。

编辑:主题启动器提供的反向操作并扩展为允许任意元素集:

function k=getIndexByCombination(v,combo) 
M=length(v);
v=sort(v);
combo=sort(combo); 
N=length(combo); 
l=0; 
%k is the index 
k=1; 
for i=1:N
    while(true)
        l=l+1;    
        if(combo(i)==v(l))
            break;
        else
            C=nchoosek(M-l,N-i);
            k=k+C;
        end
    end
end
于 2012-12-06T08:53:09.247 回答