Ich möchte alle möglichen Kombinationen der Elemente einer bestimmten Anzahl von Vektoren erzeugen.
Zum Beispiel für [1 2]
, [1 2]
und [4 5]
möchte ich die Elemente generieren:
[1 1 4; 1 1 5; 1 2 4; 1 2 5; 2 1 4; 2 1 5; 2 2 4; 2 2 5]
Das Problem ist, dass ich nicht die Anzahl der Vektoren kenne, für die ich die Kombinationen berechnen muss. Möglicherweise gibt es 3 wie in diesem Fall oder 10, und ich brauche eine Generalisierung . Können Sie mir bitte in MATLAB dabei helfen? Gibt es bereits eine vordefinierte Funktion, die diese Aufgabe erledigen kann?
Testen Sie die Funktion ALLCOMB bei FileExchange.
Wenn Sie Ihre Vektoren in einem Zellenfeld speichern, können Sie es wie folgt ausführen:
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
Betrachten Sie diese Lösung mit der Funktion 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
Oder wenn Sie eine generelle Lösung für eine beliebige Anzahl von Mengen wünschen (ohne die Variablen manuell erstellen zu müssen), verwenden Sie diese Funktionsdefinition:
function result = cartesianProduct(sets)
c = cell(1, numel(sets));
[c{:}] = ndgrid( sets{:} );
result = cell2mat( cellfun(@(v)v(:), c, 'UniformOutput',false) );
end
Wenn Sie möchten, können Sie die Ergebnisse sortieren:
cartProd = sortrows(cartProd, 1:numel(sets));
Der obige Code prüft auch nicht, ob die Sets keine doppelten Werte haben (zB: {[1 1] [1 2] [4 5]}
). Fügen Sie diese eine Zeile hinzu, wenn Sie möchten:
sets = cellfun(@unique, sets, 'UniformOutput',false);
Diese späte Antwort bietet zwei zusätzliche Lösungen, wobei die zweite die Lösung ist (meiner Meinung nach) und eine Verbesserung von Amros Antwortlösung mit ndgrid
durch Anwenden der leistungsstarken kommagetrennten Listen von MATLAB anstelle von Zellenarrays für eine hohe Leistung,
combvec
Genau wie Amro in seiner Antwort liefert die durch Kommas getrennte Listensyntax (v{:}
) Sowohl die Eingaben als auch die Ausgaben von ndgrid
. Der Unterschied (vierte Zeile) besteht darin, dass cellfun
und cell2mat
Vermieden werden, indem kommagetrennte Listen erneut als Eingaben für cat
angewendet werden:
N = numel(a);
v = cell(N,1);
[v{:}] = ndgrid(a{:});
res = reshape(cat(N+1,v{:}),[],N);
Durch die Verwendung von cat
und reshape
wird die Ausführungszeit fast halbiert. Dieser Ansatz wurde in meine Antwort auf eine andere Frage und mehr formal von Luis Mendo demonstriert.
wir können auch die 'combvec'-Anweisung in Matlab verwenden
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
Ich hoffe es hilft. Viel Glück.