I am trying to get all possible combinations of elements from an array of vectors. For example, say, I have a cell array
C = {[1 2 3 4 5], [6:13], [14 15]}
then the output should be something like
out = {[1 6 14], [1 6 15], [1 7 14], [1 7 15],....,[5 13 15]}
I tried to use a recursive function to implement this, but the code below doesn't seem to work. How can I obtain the list of all these combinations?
function [out,i] = permuteTest2(a,i,N,l,out)
if nargin == 0
a={[1 2],[4 5],[7 8]};
N = length(a);
i = 1;
out = [];
end
if i == N
out = [out, a{i}(l)];
return;
else
for k=i:N
L = length(a{k});
for l=1:L
out =[out a{k}(l)];
[out,i] =permuteTest2(a, i 1, N,l,out);
end
end
end
CodePudding user response:
Say you have a cell array C
with N vectors in it. To get all combinations of one element from each vector, you need to combine each element from the first vector with all combinations of the remaining vectors:
function combs = all_combinations(C)
a = C{1};
b = all_combinations(C(2:end));
% ... get all the combinations of a and b here
If C
has only one element, then all combinations is just that element (let's convert it to a cell array with one number in each cell, to match the expected output format):
function combs = all_combinations(C)
a = C{1};
if numel(C) == 1
combs = num2cell(a);
return;
end
b = all_combinations(C(2:end));
% ... get all the combinations of a and b here
This takes care of the recursive part. Now all we need to do is find all combinations of the two sets a
and b
:
function combs = all_combinations(C)
a = C{1};
if numel(C) == 1
combs = num2cell(a);
return;
end
b = all_combinations(C(2:end));
combs = cell(numel(a), numel(b));
for ii = 1:numel(a)
for jj = 1:numel(b)
combs{ii, jj} = [a(ii), b{jj}];
end
end
combs = combs(:);
To understand the answer above, it is important to track which elements are cell arrays and which are not, and how we index cell arrays ({}
to extract an element from the array, ()
to index parts of the cell array, creating a new cell array).
I also used numel
everywhere instead of length
. numel
is more efficient, and allows the code above to work equally well if instead of vectors you input arrays with more than one dimension.
A more robust function would test the input C
to be a cell array with at least one element, and it would test each of the elements of this cell array to be a numeric array (or vector).