problem with combvec, allcomb

How to use combvec for a huge set (a1 to a100)?
Example a1=[1 3 4], a2=[5 7], a3=[7 9 1], .... a100=[8 9 6 2]

5 commentaires

Walter Roberson
Walter Roberson le 9 Nov 2012
How many output rows do you calculate you will form?
zon
zon le 9 Nov 2012
100 in this case
Walter Roberson
Walter Roberson le 9 Nov 2012
Then I am confused by your notation. Are you working with a set with 100 elements and you need to find all the combinations of the 100 taken up to 4 at a time? Or are you working with 100 sets and you need to generate all the combinations in which one element is taken from the first set, one from the second, and so on up to one from the 100th set ? Or do you have a set of elements and you want 100 random combinations of them? Or do you have a set of elements and you want to process them 100 combinations at a time, then another 100, etc. ?
zon
zon le 9 Nov 2012
Modifié(e) : Matt Fig le 9 Nov 2012
Another example: a1=[1] a2=[3] a3=[2 6 4] a4=[8 9]. The required output is:
1 1 1 1 1 1
3 3 3 3 3 3
2 6 4 2 6 4
8 8 8 9 9 9
The order of cols. does not matter.
Walter Roberson
Walter Roberson le 9 Nov 2012
The number of results you will get will be the product of the number of elements in the sets. That could be quite a lot!!

Connectez-vous pour commenter.

Réponses (2)

Andrei Bobrov
Andrei Bobrov le 10 Nov 2012
Modifié(e) : Andrei Bobrov le 11 Nov 2012

2 votes

a = {1,3,[2 6 4],[8 9]};
c = cell(size(a));
[c{:}] = ndgrid(a{end:-1:1});
c2 = sortrows(cell2mat(cellfun(@(x)x(:),c,'un',0)),1);
out = fliplr(c2)';
ADD
n = cellfun(@numel,a);
t = max(n)./n;
while any(rem(t,1) ~= 0)
t = t*2;
end
c = cellfun(@(x,y)repmat(x,1,y),a,num2cell(t),'un',0);
out = cat(1,c{:});

3 commentaires

There seems to be a problem with this solution. For example:
a = {[1 1],[7 4 5 6],[9 8]}
Shouldn't we get this?
1 1 1 1
7 4 5 6
9 8 9 8
Also, I think that it can be fixed for small sets, but the OP seems to want something like this:
N = 100; % Even with N = 30 we will have problems (NDGRID)!
M = 4; % Or more?
a = cellfun(@(x) randi(10,1,randi(M)),cell(1,N),'Un',0);
That surely will fail with NDGRID.
Andrei Bobrov
Andrei Bobrov le 11 Nov 2012
Hi Matt! I added version (ADD).
Rik
Rik le 2 Mar 2022
Comment posted as flag by @Hang Zhang:
combvec全组合
(machine translation of the Chinese characters: "full combination")

Connectez-vous pour commenter.

Matt Fig
Matt Fig le 9 Nov 2012

0 votes

This will solve your problem.
function M = expand_vects(A)
% A is a cell array of 1-by-n vectors where n need not
% be the same in every element.
L = cellfun('length',A);
B = lcms(L);
M = zeros(length(L),B);
for ii = 1:length(L)
M(ii,:) = reshape(A{ii}(ones(1,B/L(ii)),:).',1,B);
end
Note that to use it you first need to get this file from the FEX.
Once you have the files in place, call like this:
>> A = {1,3,[2,6,4],[8,9]}; % Use a cell array
>> M = expand_vects(A)
M =
1 1 1 1 1 1
3 3 3 3 3 3
2 6 4 2 6 4
8 9 8 9 8 9

2 commentaires

You can forgo the FEX function and just use this. (I found that recursively calling LCM is just as fast or faster than the FEX function.)
function M = expand_vects(A)
% A is a cell array of 1-by-n vectors where n need not
% be the same in every element.
L = cellfun('length',A);
LC = length(L);
% B = lcms(L); % Available on the FEX. Or use below loop.
B = L(1);
for ii = 2:LC
B = lcm(B,L(ii));
end
M = zeros(LC,B);
L = B./L;
for ii = 1:LC
M(ii,:) = reshape(A{ii}(ones(1,L(ii)),:).',1,B);
end
Well.....
Simply make yourself a cell array and pass it in:
a1 = 1;
a2 = 3;
a3 = [3 4 5];
A = {a1,a2,a3};
Nasty problems like this are the reason we don't make variables a1,a2,a3,a4.....an in the first place.....

Connectez-vous pour commenter.

Catégories

En savoir plus sur Loops and Conditional Statements dans Centre d'aide et File Exchange

Question posée :

zon
le 9 Nov 2012

Commenté :

Rik
le 2 Mar 2022

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!

Translated by