Generar todas las combinaciones posibles de los elementos de algunos vectores (producto cartesiano)


Me gustaría generar todas las combinaciones posibles de los elementos de un número dado de vectores.

Por ejemplo, para [1 2], [1 2] y [4 5] quiero a 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 conozco el número 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. ¿Puede ayudarme a esto en MATLAB? ¿Hay ya un predefinido función que puede hacer esta tarea?

Author: chappjc, 2010-11-12

4 answers

Pruebe La función ALLCOMB en FileExchange.

Si almacena sus vectores en una matriz de celdas, puede ejecutarlo de la siguiente manera:

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
 16
Author: yuk,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2010-11-12 16:07:07

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 número 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 comprueba si los conjuntos no tienen valores duplicados (ej: {[1 1] [1 2] [4 5]}). Añade esta línea si quieres:

sets = cellfun(@unique, sets, 'UniformOutput',false);
 47
Author: Amro,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2010-11-12 22:06:27

Esta respuesta tardía proporciona dos soluciones adicionales, donde la segunda es la solución (en mi opinión) y una mejora en la solución de respuesta de Amro con ndgrid aplicando las poderosas listas separadas por comas de MATLAB en lugar de matrices de celdas para un alto rendimiento,{[13]]}

  1. Si tiene la Caja de herramientas de la Red neuronal: use combvec
  2. Si lo hace no tiene la caja de herramientas, como suele ser el caso: a continuación hay otra forma de generalizar el producto cartesiano para cualquier número de conjuntos.

Al igual que Amro hizo en su respuesta, la sintaxis de listas separadas por comas (v{:}) suministra 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 las entradas a cat:

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

El uso de cat y reshape reduce 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 .

 11
Author: chappjc,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-05-23 10:31:06

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 que ayude. Buena suerte.

 0
Author: Akhil Appu Shetty,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-01-13 20:40:35