2010-11-12 16 views
31

Ich möchte alle möglichen Kombinationen der Elemente einer bestimmten Anzahl von Vektoren generieren.Generieren Sie alle möglichen Kombinationen der Elemente einiger Vektoren (kartesisches Produkt)

Zum Beispiel für [1 2], [1 2] und [4 5] ich die Elemente erzeugen möchten:

[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 die Anzahl der Vektoren nicht wissen, für die ich die Kombinationen berechnen müssen . Es könnte 3 als in diesem Fall sein, oder es kann 10 sein, und ich brauche eine Generalisierung. Kannst du mir bitte in MATLAB helfen? Gibt es bereits eine vordefinierte Funktion, die diese Aufgabe übernehmen kann?

+10

was Sie suchen, wird das 'kartesische Produkt' der Vektoren genannt. Vielleicht haben Sie dafür etwas Glück. –

Antwort

16

Versuchen Sie ALLCOMB Funktion bei FileExchange.

Wenn Sie Sie Vektoren in einem Zellenfeld speichern, können Sie es wie folgt aus:

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 
+6

Beachten Sie, dass "ALLCOMB" 'NDGRID' im Wesentlichen auf die gleiche Weise wie in Amros Antwort verwendet, mit Fehler-Proofing oben. – lodhb

+0

Ja danke genau das, was ich gesucht habe .. :-) – tim

46

Betrachten Sie diese Lösung mit der NDGRID Funktion:

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 allgemeine Lösung Verwenden Sie für jede beliebige Anzahl von Sätzen (ohne die Variablen manuell erstellen zu müssen) diese Funktionsdefinition:

function result = cartesianProduct(sets) 
    c = cell(1, numel(sets)); 
    [c{:}] = ndgrid(sets{:}); 
    result = cell2mat(cellfun(@(v)v(:), c, 'UniformOutput',false)); 
end 

Beachten Sie, dass wenn Sie es vorziehen, können Sie die Ergebnisse sortieren:

cartProd = sortrows(cartProd, 1:numel(sets)); 

Auch dann, wenn Sie den obigen Code nicht überprüfen, ob die Sätze keine doppelten Werte (zB: {[1 1] [1 2] [4 5]}) haben. Fügen Sie diese eine Zeile, wenn Sie wollen:

sets = cellfun(@unique, sets, 'UniformOutput',false); 
11

Diese späten Antworten liefern zwei weitere Lösungen, bei denen die zweiten die Lösung (meiner Meinung nach) ist und eine Verbesserung Antwort-Lösung Amro mit ndgrid durch Anwendung MATLAB leistungsstarken kommagetrennte Listen anstelle von Zellen-Arrays für hohe Leistung,

  1. Wenn Sie die Neural Network Toolbox haben: combvec
  2. verwenden Wenn Sie nicht tun habe die Toolbox, wie es normalerweise der Fall ist: Unten ist eine andere Möglichkeit, das kartesische Produkt für eine beliebige Anzahl von Sets zu verallgemeinern.

Wie Amro in seiner Antwort hat, die durch Kommata getrennte Listen Syntax (v{:}) liefert sowohl die Ein- und Ausgänge von ndgrid. Die Differenz (vierte Zeile) ist, dass es vermeidet cellfun und cell2mat durch Komma getrennte Listen der Anwendung wieder, nun als die Eingänge zu cat:

N = numel(a); 
v = cell(N,1); 
[v{:}] = ndgrid(a{:}); 
res = reshape(cat(N+1,v{:}),[],N); 

Die Verwendung von cat und reshape schneidet fast Ausführungszeit in der Hälfte. Dieser Ansatz wurde in my answer to an different question und more formally by Luis Mendo demonstriert.

0

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 

Hoffe, es hilft. Viel Glück.

Verwandte Themen