2011-12-13 18 views
5

¿Existe un comando o una estrategia de línea en MATLAB que devolverá todas las combinaciones de los componentes de las matrices de celdas n, tomadas n a la vez?MATLAB: Combinaciones de un número arbitrario de matrices de celdas

Un ejemplo de lo que quiero lograr:

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

El comando sería capaz de aceptar un número arbitrario de argumentos y el resultado del ejemplo sería tener tantas columnas como argumentos a la función . (Por supuesto, la sintaxis anterior solo está destinada a la ilustración y cualquier método que genere los resultados sea cual sea el formato que se ajuste a la factura)

EDIT: preguntas similares han sido hechas para matrices en lugar de celdas, p. link. Muchas soluciones apuntan a la presentación de FEX allcomb, pero todas estas soluciones son solo envoltorios alrededor de ndgrid, que solo funciona con dobles. ¿Alguna sugerencia para conjuntos no numéricos?

+1

Se puede usar una solución que funciona para los números enteros ajustar y luego piense en el resultado (las combinaciones) como los índices de sus matrices de celdas. – Aabaz

+2

Muy relacionado: [Matlab - Genera todas las combinaciones posibles de los elementos de algunos vectores] (http://stackoverflow.com/q/4165859/52738), [MATLAB: enumerando todas las combinaciones de elementos en un número arbitrario de conjuntos] (http://stackoverflow.com/q/6607355/52738), [¿Cómo puedo crear todas las combinaciones de caracteres en conjuntos de texto?] (http://stackoverflow.com/q/5623120/52738). Los primeros dos tratan con vectores numéricos, y el tercero trata con arreglos de caracteres, pero la solución subyacente es efectivamente la misma para las matrices de celdas. – gnovice

Respuesta

6

Aunque dirijo este en my answer a un related/near duplicate question, les dejo una versión diferente de mi solución a este problema, ya que parece que desea una solución generalizada y mi otra respuesta es específica para el caso de tres conjuntos de entrada. Aquí es una función que debe hacer lo que quiere para cualquier número de entradas de la matriz celular:

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 

Y así es como ustedes lo llaman:

>> combMat = allcombs(A, B) 

combMat = 

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

Gracias por la respuesta muy útil, @gnovice. – foglerit

5

Una estrategia de 2 líneas:

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

Muy simple y limpio, me gusta mucho. Acepté la respuesta de gnovice por la generalidad, pero tu respuesta fue muy útil para entender la suya. – foglerit

Cuestiones relacionadas