使用 MATLAB 不重复地生成所有组合

Generating all combinations without repetition using MATLAB

我有 4 个集合,每个集合包含 6 个元素,我想从中生成所有可能的大小为 8 的向量,前两个元素来自 set1,第二个 2 来自 set2,第三个 2 来自 set3,第四个 2 来自 set4,点中没有重复从每个集合中取出元素 1,2 / 3,4 / 5,6/ 7,8 总是不同的。我的目标数字组合是 (6choose2)^4 。请帮忙。

    D1=[2+2i,2+1i,1+2i,1+1i,2,1i];
    D2=[-2+2i,-2+1i,-1+2i,-1+1i,-1,2i];
    D3=[-2-2i,-2-i,-1-i,-1-1i,-2,-1i];
    D4=[2-2i,2-i,1-2i,-1+1i,1,-2i];

所以我找到了一种获取组合的方法。你真的应该给出一个更简单的例子来解释你的问题(我就是这样解决的)。

程序是:

  • 获取每个集合的所有 {2 element} 个唯一组合。
  • 然后为你得到的结果建立一个索引。通常每个子集都应该有一个索引,但由于它们的长度都相同,因此唯一组合的数量将相同,因此您可以重复使用 4 倍的相同索引。
  • 得到这4组指标的所有组合
  • 最后,根据索引组合重建最终矩阵

代码如下:

%// prepare a few helper numbers
nSets = 4 ;
nElemPerSet = 2 ;
nCombs =  nchoosek( numel(D1) ,nElemPerSet).^nSets ; %// <= nCombs=50625

%// for each set, get the unique combinations of 2 elements
s1 = nchoosek( D1 , nElemPerSet ) ;
s2 = nchoosek( D2 , nElemPerSet ) ;
s3 = nchoosek( D3 , nElemPerSet ) ;
s4 = nchoosek( D4 , nElemPerSet ) ;

%// now get the index of all the combinations of the above subsets
s = 1:size(s1,1) ;
combindex = all_combinations( repmat({s},1,4) ) ; %// <= size(combindex)=[50625 4]

%// now rebuild the full combinations based on above indices
combinations = zeros( nCombs , nSets*nElemPerSet ) ;
for ic = 1:nCombs
    combinations(ic,:) = [s1(combindex(ic,1),:) s2(combindex(ic,2),:) s3(combindex(ic,3),:) s4(combindex(ic,4),:)] ;
end

可能有一种方法可以通过巧妙地使用 arrayfun 来摆脱最后一个循环,但我将其留作 reader.

的练习。

此代码适用于您问题中所述的 D1, D2, D3 and D4 初始值,但如果您或任何人想要 运行 逐步了解正在发生的事情,我强烈建议您尝试它具有更简单的起始值。类似于:

%// define 4 non-complex sets of 4 values each (all different)
nVal=4 ;
D1 = 1:nVal ;
D2 = D1(end)+1:D1(end)+nVal ;
D3 = D2(end)+1:D2(end)+nVal ;
D4 = D3(end)+1:D3(end)+nVal ;

注意函数的使用all_combinations。这只是我在评论中提到的答案(Generate a matrix containing all combinations of elements taken from n vectors)重新打包在一个函数中。如果你经常处理组合问题,我建议你看一下并将其添加为书签(如果它对你有帮助,你也可以投票,它在这里)。

重新封装后的函数为:

function combs = all_combinations( vectors )
%// function combs = all_combinations( vectors )
%//
%// example input :
%//     vectors = { [1 2], [3 6 9], [10 20] }; %//cell array of vectors
%//
%// Credit: Luis Mendo : 

n = numel(vectors);             %// number of vectors
combs = cell(1,n);              %// pre-define to generate comma-separated list
[combs{end:-1:1}] = ndgrid(vectors{end:-1:1}); %// the reverse order in these two
%// comma-separated lists is needed to produce the rows of the result matrix in
%// lexicographical order 
combs = cat(n+1, combs{:});     %// concat the n n-dim arrays along dimension n+1
combs = reshape(combs,[],n);    %// reshape to obtain desired matrix