Je voudrais générer toutes les combinaisons possibles des éléments d'un nombre donné de vecteurs.
Par exemple, pour [1 2]
, [1 2]
et [4 5]
, je souhaite générer les éléments:
[1 1 4; 1 1 5; 1 2 4; 1 2 5; 2 1 4; 2 1 5; 2 2 4; 2 2 5]
Le problème est que je ne connais pas le nombre de vecteurs pour lesquels je dois calculer les combinaisons. Il peut y en avoir 3 comme dans ce cas, ou il peut y en avoir 10, et j’ai besoin d’une généralisation. Pouvez-vous m'aider s'il vous plaît à cela dans MATLAB? Existe-t-il déjà une fonction prédéfinie pouvant effectuer cette tâche?
Essayez ALLCOMB function à FileExchange.
Si vous stockez des vecteurs dans un tableau de cellules, vous pouvez l'exécuter comme suit:
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
Considérez cette solution en utilisant la fonction NDGRID :
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
Ou si vous souhaitez une solution générale pour un nombre quelconque d'ensembles (sans avoir à créer les variables manuellement), utilisez cette définition de fonction:
function result = cartesianProduct(sets)
c = cell(1, numel(sets));
[c{:}] = ndgrid( sets{:} );
result = cell2mat( cellfun(@(v)v(:), c, 'UniformOutput',false) );
end
Notez que si vous préférez, vous pouvez trier les résultats:
cartProd = sortrows(cartProd, 1:numel(sets));
De plus, le code ci-dessus ne vérifie pas si les ensembles n'ont pas de valeurs en double (ex: {[1 1] [1 2] [4 5]}
). Ajoutez cette ligne si vous voulez:
sets = cellfun(@unique, sets, 'UniformOutput',false);
Cette réponse tardive fournit deux solutions supplémentaires, la seconde étant la solution (à mon avis) et une amélioration de la solution de réponse d'Amro avec ndgrid
en appliquant les puissantes listes MATLAB séparées par des virgules au lieu de tableaux de cellules pour des performances élevées
combvec
Comme Amro dans sa réponse, la syntaxe des listes séparées par des virgules (v{:}
) fournit à la fois les entrées et les sorties de ndgrid
. La différence (quatrième ligne) réside dans le fait qu’elle évite cellfun
et cell2mat
en appliquant des listes séparées par des virgules, là encore, en tant qu’entrées dans cat
:
N = numel(a);
v = cell(N,1);
[v{:}] = ndgrid(a{:});
res = reshape(cat(N+1,v{:}),[],N);
L'utilisation de cat
et reshape
réduit le temps d'exécution de près de moitié. Cette approche a été démontrée dans ma réponse à une question différente , et plus formellement de Luis Mendo .
nous pouvons également utiliser l'instruction 'combvec' dans 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
J'espère que ça vous aidera ... Bonne chance.