找到你要的答案

Q:Generating all combinations without repetition using MATLAB

Q:生成所有组合没有重复使用MATLAB

i have 4 sets each contain 6 elements from which I want to generate all possible vectors of size 8 were the first two elements are from set1 second 2 from set2 third 2 from set3 forth 2 from set4 without repetition in the points taken from each set such that the elements 1,2 / 3,4 / 5,6/ 7,8 are always different. My target number combinations is (6choose2)^4 . Any help please.

    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];

我有4套,每个包含6个元素,我想产生大小为8的所有可能的载体,第一个元素是从2从第三,第二套2从3第四2从SET4没有采取从每个设置这样的元素1 / 3 / 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];
answer1: 回答1:

So I found a way to get your combinations. You should really have given an more minimal example to explain your problem (that's how I solved it by the way).

The procedure is:

  • Get all the {2 element} unique combination for each set.
  • Then build an index of the result you obtain. Normally there should be an index for each subset but since they are all the same length, the number of unique combinations will be the same so you can just reuse 4x the same index.
  • Get all the combinations of these 4 sets of indices
  • Finally, rebuild the final matrix based on the indices combinations

The code look like:

%// 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

There is probably a way to get rid of the last loop with an intelligent use of arrayfun but I leave that as an exercise to the reader.

This code works for your initial values of D1, D2, D3 and D4 as described in your question, but if you or anybody want to run it step by step to understand what's happening, I strongly recommend to try it with much simpler starting values. Something like:

%// 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 ;

Note the use of the function all_combinations. This is just the answer I was mentioning in the comment (Generate a matrix containing all combinations of elements taken from n vectors) repackaged in a function. I suggest you have a look and bookmark it if you deal with combination problem often (also you can upvote it if it helps you, which it does here).

The repackaged function is:

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 : http://stackoverflow.com/questions/21895335/generate-a-matrix-containing-all-combinations-of-elements-taken-from-n-vectors

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

所以我找到了一个方法来得到你的组合。你应该给一个更简单的例子来解释你的问题(这就是我如何解决它的方式)。

程序是:

  • Get all the {2 element} unique combination for each set.
  • Then build an index of the result you obtain. Normally there should be an index for each subset but since they are all the same length, the number of unique combinations will be the same so you can just reuse 4x the same index.
  • Get all the combinations of these 4 sets of indices
  • Finally, rebuild the final matrix based on the indices combinations

代码看起来像:

%// 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智能使用最后一环但我离开,作为读者的练习。

此代码为你最初的D1、D2值,D3和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。这是我在评论中提到的答案(生成一个矩阵包含从n个向量元素的所有组合)包装在一个函数。我建议你看看书签如果你处理组合问题经常(也可以支持它如果它帮助你,它不在这里)。

包装的功能是:

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 : http://stackoverflow.com/questions/21895335/generate-a-matrix-containing-all-combinations-of-elements-taken-from-n-vectors

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
matlab  combinations