Necesito crear una lista de combinaciones de números. Los números son bastante pequeños, por lo que puedo usar en byte
lugar de int
. Sin embargo, requiere muchos bucles anidados para obtener todas las combinaciones posibles. Me pregunto si hay una manera más eficiente de hacer lo que busco. El código hasta ahora es:
var data = new List<byte[]>();
for (byte a = 0; a < 2; a++)
for (byte b = 0; b < 3; b++)
for (byte c = 0; c < 4; c++)
for (byte d = 0; d < 3; d++)
for (byte e = 0; e < 4; e++)
for (byte f = 0; f < 3; f++)
for (byte g = 0; g < 3; g++)
for (byte h = 0; h < 4; h++)
for (byte i = 0; i < 2; i++)
for (byte j = 0; j < 4; j++)
for (byte k = 0; k < 4; k++)
for (byte l = 0; l < 3; l++)
for (byte m = 0; m < 4; m++)
{
data.Add(new [] {a, b, c, d, e, f, g, h, i, j, k, l, m});
}
Estaba considerando usar algo como un BitArray
pero no estoy seguro de cómo podría incorporarlo.
Cualquier recomendación sería muy apreciada. Alternativamente, ¿quizás esta es la forma más rápida de hacer lo que quiero?
EDITAR Un par de puntos rápidos (y disculpas, no los puse en la publicación original):
- Los números y el orden de ellos (2, 3, 4, 3, 4, 3, 3, etc.) son muy importantes, por lo que usar una solución como Generar permutaciones usando LINQ no ayudará porque los máximos en cada 'columna' son diferente
- No soy matemático, así que me disculpo si no estoy usando los términos técnicos como 'permutaciones' y 'combinaciones' correctamente :)
- Yo no necesito para llenar todas estas combinaciones a la vez - no puedo agarrar uno u otro basado en un índice
- Usar
byte
es más rápido que usarint
, te lo garantizo . También es mucho mejor en el uso de la memoria tener más de 67m matrices de bytes en lugar de ints - Mi objetivo final aquí es buscar una alternativa más rápida a los bucles anidados.
- Consideré usar programación paralela, pero debido a la naturaleza iterativa de lo que estoy tratando de lograr, no pude encontrar la manera de hacerlo con éxito (incluso con
ConcurrentBag
); sin embargo, estoy feliz de que me hayan demostrado que estoy equivocado :)
CONCLUSIÓN
Caramiriel ha proporcionado una buena microoptimización que reduce algo de tiempo en los bucles, por lo que he marcado esa respuesta como correcta. Eric también mencionó que es más rápido preasignar la Lista. Pero, en esta etapa, parece que los bucles anidados son de hecho la forma más rápida posible de hacer esto (deprimente, ¡lo sé!).
Si desea probar exactamente lo que estaba tratando de comparar StopWatch
, vaya con 13 bucles contando hasta 4 en cada bucle, lo que hace aproximadamente 67m + líneas en la lista. En mi máquina (i5-3320M 2.6GHz) se necesitan alrededor de 2.2s para hacer la versión optimizada.