Para una lista dada de conjuntos donde los elementos de los conjuntos no comparten ningún elemento entre los conjuntos, quiero calcular todas las combinaciones posibles donde una combinación puede tener hasta un elemento por conjunto. Por ejemplo:
{{a}, {b1, b2}}
Produciría:
{ Ø, {a}, {b1}, {b2}, {a, b1}, {a, b2}}
Supuse que para cualquier juego múltiple dado con conjuntos donde conjunto tiene elementos hay:
{0, 0} - Ø
{0, 1} - b1
{0, 2} - b2
{1, 0} - a
{1, 1} - a, b1
{1, 2} - a, b2
Luego uso esos números para asignarlos a los números en los conjuntos. Esto funciona, pero para realizar un seguimiento de qué número debe fluir y cuáles deben restablecerse, tengo que revisar cada número en el registro.
¿Existe una forma más eficiente, por ejemplo, codificar todos los estados diferentes en un solo número? Intenté hacer esto con un número binario e intenté determinar el elemento del conjunto con operaciones bit a bit, pero me encontré con un problema en el que este ejemplo no funciona:
0|00 - Ø
0|01 - b1
0|10 - b2
1|00 - a <-- the consecutive number here would be 011
1|01 - a, b1
1|10 - a, b2
Sí, hay una manera más eficiente. Dejar
Dejar . Tenga en cuenta que hay posibilidades de , entonces define nuestra elección para el primer conjunto.
Dejar . Del mismo modo, hay valores posibles para , entonces determina nuestra elección del segundo conjunto.
Dejar . determina la elección del tercer set.
Etcétera. En general, para calcular de , para cada , calculas el producto (cuando , este es un producto vacío, igual a ), luego calcule la división redondeada hacia abajo de dividido por ese producto, y finalmente establecer ser el resultado de esa división módulo .
Esto significa que te da una lista que determina su selección por completo. Cada da una selección única, no se saltan números.
Esta es una buena tarea para un algoritmo recursivo: Para cada elemento del primer conjunto, iterar recursivamente a través de las combinaciones de los conjuntos restantes, anteponiendo a cada uno
También hay una función de biblioteca de Python itertools.product
que hace la mayor parte del trabajo:
import itertools
mysets = [[None, "a"], [None, "b1", "b2"]]
for combi in itertools.product(*mysets):
print(combi)
salidas:
(None, None)
(None, 'b1')
(None, 'b2')
('a', None)
('a', 'b1')
('a', 'b2')
SlipEterno
Mahoní
SlipEterno
Mahoní
Carlos
Mahoní
DanielV
Mahoní
DanielV
Mahoní
DanielV