vectores multiplicacion matrices combinaciones codigo matlab combinatorics cartesian-product

matlab - multiplicacion - Genera todas las combinaciones posibles de los elementos de algunos vectores(producto cartesiano)



combinaciones de vectores matlab (4)

Me gustaría generar todas las combinaciones posibles de los elementos de una cantidad dada de vectores.

Por ejemplo, para [1 2] , [1 2] y [4 5] quiero generar los elementos:

[1 1 4; 1 1 5; 1 2 4; 1 2 5; 2 1 4; 2 1 5; 2 2 4; 2 2 5]

El problema es que no sé la cantidad de vectores para los que necesito calcular las combinaciones. Puede haber 3 como en este caso, o puede haber 10, y necesito una generalización . ¿Puedes ayudarme con esto en MATLAB? ¿Ya hay una función predefinida que puede hacer esta tarea?


Considere esta solución usando la función 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

O si desea una solución general para cualquier cantidad de conjuntos (sin tener que crear las variables manualmente), use esta definición de función:

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

Tenga en cuenta que si lo prefiere, puede ordenar los resultados:

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

Además, el código anterior no verifica si los conjuntos no tienen valores duplicados (por ejemplo: {[1 1] [1 2] [4 5]} ). Agregue esta línea si lo desea:

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


Esta última respuesta proporciona dos soluciones adicionales, mientras que la segunda es la solución (en mi opinión) y una mejora en la solución de respuesta de Amro con ndgrid mediante la aplicación de poderosas listas separadas por comas de MATLAB en lugar de matrices de células para un alto rendimiento.

  1. Si tiene Neural Network Toolbox: use combvec
  2. Si no tiene la caja de herramientas, como suele ser el caso, a continuación encontrará otra forma de generalizar el producto cartesiano para cualquier cantidad de conjuntos.

Tal como lo hizo Amro en su respuesta, la sintaxis de las listas separadas por comas ( v{:} ) proporciona tanto las entradas como las salidas de ndgrid . La diferencia (cuarta línea) es que evita cellfun y cell2mat aplicando listas separadas por comas, nuevamente, ahora como entradas para cat :

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

El uso del cat y la reshape reducen el tiempo de ejecución casi a la mitad. Este enfoque fue demostrado en mi respuesta a una pregunta diferente , y más formalmente por Luis Mendo .


Pruebe la función ALLCOMB en FileExchange.

Si almacena sus vectores en una matriz de celdas, puede ejecutarlo así:

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


también podemos usar la instrucción ''combvec'' en 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

Espero eso ayude. Buena suerte.