问题
I would like to generate all the possible combinations of the elements of a given number of vectors.
For example, for [1 2]
, [1 2]
and [4 5]
I want to generate the elements:
[1 1 4; 1 1 5; 1 2 4; 1 2 5; 2 1 4; 2 1 5; 2 2 4; 2 2 5]
The problem is that I don\'t know the number of vectors for which I need to calculate the combinations. There might be 3 as in this case, or there may be 10, and I need a generalization. Can you please help me to this in MATLAB? Is there already a predefined function that can do this task?
回答1:
Try ALLCOMB function at FileExchange.
If you store you vectors in a cell array, you can run it like this:
a = {[1 2], [1 2], [4 5]};
allcomb(a{:})
ans =
1 1 4
1 1 5
1 2 4
1 2 5
2 1 4
2 1 5
2 2 4
2 2 5
回答2:
Consider this solution using the NDGRID function:
sets = {[1 2], [1 2], [4 5]};
[x y z] = ndgrid(sets{:});
cartProd = [x(:) y(:) z(:)];
cartProd =
1 1 4
2 1 4
1 2 4
2 2 4
1 1 5
2 1 5
1 2 5
2 2 5
Or if you want a general solution for any number of sets (without having to create the variables manually), use this function definition:
function result = cartesianProduct(sets)
c = cell(1, numel(sets));
[c{:}] = ndgrid( sets{:} );
result = cell2mat( cellfun(@(v)v(:), c, 'UniformOutput',false) );
end
Note that if you prefer, you can sort the results:
cartProd = sortrows(cartProd, 1:numel(sets));
Also, the code above does not check if the sets have no duplicate values (ex: {[1 1] [1 2] [4 5]}
). Add this one line if you want to:
sets = cellfun(@unique, sets, 'UniformOutput',false);
回答3:
This late answers provides two additional solutions, where the second is the solution (in my opinion) and an improvement on Amro's answer solution with ndgrid
by applying MATLAB's powerful comma-separated lists instead of cell arrays for high performance,
- If you have the Neural Network Toolbox: use combvec
- If you do not have the toolbox, as is usually the case: below is another way to generalize the Cartesian product for any number of sets.
Just as Amro did in his answer, the comma-separated lists syntax (v{:}
) supplies both the inputs and outputs of ndgrid
. The difference (fourth line) is that it avoids cellfun
and cell2mat
by applying comma-separated lists, again, now as the inputs to cat
:
N = numel(a);
v = cell(N,1);
[v{:}] = ndgrid(a{:});
res = reshape(cat(N+1,v{:}),[],N);
The use of cat
and reshape
cuts execution time almost in half. This approach was demonstrated in my answer to an different question, and more formally by Luis Mendo.
回答4:
we can also use the 'combvec' instruction in matlab
no_inp=3 % number of inputs we want...in this case we have 3 inputs
a=[1 2 3]
b=[1 2 3]
c=[1 2 3]
pre_final=combvec(c,b,a)';
final=zeros(size(pre_final));
for i=1:no_inp
final(:,i)=pre_final(:,no_inp-i+1);
end
final
Hope it helps. Good luck.
来源:https://stackoverflow.com/questions/4165859/generate-all-possible-combinations-of-the-elements-of-some-vectors-cartesian-pr