Générer toutes les combinaisons possibles des éléments de certains vecteurs (produit Cartésien)
je tiens à générer toutes les combinaisons possibles des éléments d'un certain nombre de vecteurs.
Par exemple, pour [1 2]
, [1 2]
et [4 5]
je veux 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 sais pas le nombre de vecteurs pour lesquels je dois calculer les combinaisons. Il pourrait y en avoir 3 comme dans ce cas, ou il pourrait y en avoir 10, et j'ai besoin d'un généralisation . Tu peux m'aider à faire ça à MATLAB? Il y a déjà une fonction prédéfinie qui peut faire cette tâche?
4 réponses
envisager cette solution en utilisant la NDGRID fonction:
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 voulez une solution générale pour n'importe quel nombre 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));
aussi, le code ci-dessus ne vérifie pas si les ensembles n'ont pas de duplicata valeurs (ex: {[1 1] [1 2] [4 5]}
). Ajouter cette ligne si vous voulez:
sets = cellfun(@unique, sets, 'UniformOutput',false);
ces réponses tardives offrent deux solutions supplémentaires, dont la seconde est la solution (à mon avis) et une amélioration de la solution de réponse D'Amro avec ndgrid
en appliquant les puissantes listes séparées par des virgules de MATLAB au lieu de réseaux cellulaires pour une haute performance,
- si vous avez la boîte à outils du réseau neuronal: utiliser
combvec
- si vous faites Non ont la boîte à outils, comme est généralement le cas: ci-dessous est une autre façon de généraliser le produit cartésien pour un certain nombre d'ensembles.
tout 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) est qu'il évite cellfun
et cell2mat
en appliquant des listes séparées par des virgules, encore une fois, maintenant que les entrées à 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 presque la moitié. Cette approche a été démontrée dans ma réponse à une question différente , et plus formellement par 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 aidera. Bonne chance.