Arrays 1:M中N个项的智能线性索引有序元组

Arrays 1:M中N个项的智能线性索引有序元组,arrays,matlab,indexing,combinatorics,Arrays,Matlab,Indexing,Combinatorics,我希望使用线性索引对m-choose-N元组进行索引。不久前,我为M choose 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。到目前为止,我一直在做一个

我希望使用线性索引对m-choose-N元组进行索引。不久前,我为M choose 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

正如Jerad所评论的,您可以使用nchoosekv,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
相反的操作是类似的:只需对组合进行排序并检查元素,检查当前组合是否在该范围内

编辑:topic starter提供的反向操作,可扩展为允许任意元素集:

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

除非我误解了你,否则你可以使用内置函数,其中v是元素的向量。我必须承认我不知道nchoosekv,k的向量功能,但你的解决方案非常优雅,即使对于大m,速度也令人印象深刻。唯一的变化是,l=l+1语句应该在计算C之前进行,即:l=l+1;C=nchoosekM-l,N-i;谢谢,我会修正你的评论,但我也应该从0开始选择v1。如果其他人访问此线程,则反向操作:函数k=getIndexByCombinationcombo,M combo=sortcombo;N=长度组合;l=0;%k是指数k=1;对于i=1:N`whiletrue``l=l+1;`C=nchoosekM-l,N-i;`ifcomboi==l``break;``else``k=k+C;``结束``结束``结束`