2011-12-13 14 views
5

Esiste un comando o una strategia di una riga in MATLAB che restituirà tutte le combinazioni dei componenti degli array di celle n, prese n alla volta?MATLAB: Combinazioni di un numero arbitrario di matrici di celle

Un esempio di quello che voglio realizzare:

A = {'a1','a2'}; 
B = {'b1','b2','b3'}; 
C = combinations(A,B) 
C = {'a1','b1' ; 
    'a1','b2' ; 
    'a1','b3' ; 
    'a2','b1' ; 
    'a2','b2' ; 
    ... } 

Il comando sarebbe in grado di accettare un numero arbitrario di argomenti e il risultato nell'esempio avrebbe tante colonne quante sono argomenti per la funzione . (Naturalmente, la sintassi sopra è solo per l'illustrazione e qualsiasi metodo che genererebbe i risultati indipendentemente dal formato della fattura)

MODIFICA: domande simili sono state poste per matrici anziché celle, ad es. link. Molte soluzioni puntano alla sottomissione FEX allcomb, ma tutte queste soluzioni sono solo wrapper su ndgrid, che funzionano solo con il doppio. Qualche suggerimento per set non numerici?

+1

Si potrebbe utilizzare una soluzione che funziona per gli interi set e poi pensa al risultato (le combinazioni) come agli indici dei tuoi array di celle. – Aabaz

+2

Strettamente correlati: [Matlab: genera tutte le combinazioni possibili degli elementi di alcuni vettori] (http://stackoverflow.com/q/4165859/52738), [MATLAB: Enumerazione di tutte le combinazioni di elementi in un numero arbitrario di insiemi] (http://stackoverflow.com/q/6607355/52738), [Come posso creare tutte le combinazioni di caratteri in insiemi di testo?] (http://stackoverflow.com/q/5623120/52738). I primi due riguardano i vettori numerici e il terzo riguarda gli array di caratteri, ma la soluzione sottostante è effettivamente la stessa per gli array di celle. – gnovice

risposta

6

Anche se mi rivolgo in my answer ad un related/near duplicate question, sto postando una versione diversa della mia soluzione qui dal momento che appare si desidera una soluzione generalizzata , e la mia altra risposta è specifica per il caso di tre set di input. Ecco una funzione che dovrebbe fare quello che vuoi per qualsiasi numero di ingressi della matrice cellulare:

function combMat = allcombs(varargin) 
    sizeVec = cellfun('prodofsize', varargin); 
    indices = fliplr(arrayfun(@(n) {1:n}, sizeVec)); 
    [indices{:}] = ndgrid(indices{:}); 
    combMat = cellfun(@(c,i) {reshape(c(i(:)), [], 1)}, ... 
        varargin, fliplr(indices)); 
    combMat = [combMat{:}]; 
end 

Ed ecco come si potrebbe chiamare:

>> combMat = allcombs(A, B) 

combMat = 

    'a1' 'b1' 
    'a1' 'b2' 
    'a1' 'b3' 
    'a2' 'b1' 
    'a2' 'b2' 
    'a2' 'b3' 
+0

Grazie per la risposta molto utile, @gnovice. – foglerit

5

Una strategia 2-line:

A = {'a1','a2'}; 
B = {'b1','b2','b3'}; 

[a b]=ndgrid(1:numel(A),1:numel(B)); 
C= [A(a(:))' B(b(:))'] 

C = 
    'a1' 'b1' 
    'a2' 'b1' 
    'a1' 'b2' 
    'a2' 'b2' 
    'a1' 'b3' 
    'a2' 'b3' 
+0

Molto semplice e pulito, mi piace molto. Ho accettato la risposta di gnovice per la generalità, ma la tua risposta è stata molto utile per capire il suo. – foglerit

Problemi correlati