Cómo convertir una combinación dada a un solo número

La respuesta de Alexander Farrugia resuelve el problema maravillosamente, pero no pude resistir jugar un poco más, y aquí hay un pseudocódigo en caso de que sea útil para alguien. La implementación es simple y razonablemente eficiente. En particular, una buena propiedad de la función de decodificación es que evita el cálculo de cualquier binomio, y pasa solo una vez sobre las 24 bolas.

De bolas a número:

función codificar (bolas []) {
N = 0
para bola = 0..length (bolas) -1 {
N + = binomio (bolas [bola] -1, longitud (bolas) -bola)
}
devolver N
}

Entonces, por ejemplo, encode([23,17,11,4]) = 7923 . El binomio (n, m) debería devolver 0 en caso de que m> n.

De número a bolas:

función de decodificación (N, bolasLeft, totBalls) {
resultado = ()
binom = binomial (totBalls, ballsLeft)
para b = totBalls..1 por -1 {
si binom <= N {
agregue b + 1 al resultado
N – = binom
binom = binom * ballsLeft / (b-ballsLeft + 1)
bolasIzquierda–
}
binom = binom * (b-ballsLeft) / b
}
}

Entonces, decode(7923, 4, 24) = [23,17,11,4] .

Si b es el número de bolas a codificar yn es el número total de bolas, entonces la codificación se realiza en O (b ^ 2), donde un factor b proviene del cálculo de los binomios, y la decodificación toma O (n).

Usando una búsqueda binaria, las asintóticas de la decodificación se pueden cambiar a O (b ^ 2 log n), pero eso sacrifica la elegancia del algoritmo y solo es útil si n es enorme en comparación con b.

Según el sistema de numeración combinatoria, la biyección que está buscando es la siguiente:

Si ha elegido las cuatro bolas [matemáticas] c_1> c_2> c_3> c_4 [/ matemáticas] (estamos, sin pérdida de generalidad, ordenándolas en orden decreciente), entonces el número correspondiente a ellas es

[matemáticas] \ displaystyle N = \ binom {c_1-1} {4} + \ binom {c_2-1} {3} + \ binom {c_3-1} {2} + \ binom {c_4-1} {1} .[/mates]

Lo anterior asigna las bolas [matemáticas] 1,2,3,4 [/ matemáticas] al número [matemáticas] 0 [/ matemáticas] y las bolas [matemáticas] 21,22,23,24 [/ matemáticas] al número [matemáticas] 10625 [/ matemáticas]. Aquí estamos asumiendo que [math] \ displaystyle \ binom {n} {m} = 0 [/ math] if [math] n

Por ejemplo: las bolas [matemáticas] 4, 11, 17, 23 [/ matemáticas] que menciona en su ejemplo se asignarán al número [matemáticas] \ displaystyle \ binom {22} {4} + \ binom {16} { 3} + \ binom {10} {2} + \ binom {3} {1} = 7315 + 560 + 45 + 3 = 7923. [/ Matemáticas]

Para recuperar las 4 bolas originales del número [math] 7923 [/ math], el algoritmo es el siguiente. Primero, evalúe [math] \ binom {4} {4}, \ binom {5} {4}, \ ldots [/ math] hasta que la respuesta exceda [math] 7923 [/ math]. En este caso, [matemática] \ binom {22} {4} = 7315 [/ matemática] y [matemática] \ binom {23} {4} = 8855 [/ matemática], entonces la primera bola es [matemática] 23 [ /mates]. Restamos [matemática] 7923 – \ binom {22} {4} [/ matemática] para obtener [matemática] 608 [/ matemática], luego evaluamos [matemática] \ binom {3} {3}, \ binom {4} { 3}, \ ldots [/ math] hasta que la respuesta exceda [math] 608 [/ math]. En este caso, [matemática] \ binom {16} {3} = 560 [/ matemática] y [matemática] \ binom {17} {3} = 680 [/ matemática], entonces la segunda bola es [matemática] 17 [ /mates]. Restamos [matemáticas] 608 – \ binom {16} {3} = 48 [/ matemáticas], luego evaluamos [matemáticas] \ binom {2} {2}, \ binom {3} {2}, \ ldots [/ matemáticas ] hasta que la respuesta exceda [matemáticas] 48 [/ matemáticas]. En este caso, [matemática] \ binom {10} {2} = 45 [/ matemática] y [matemática] \ binom {11} {2} = 55 [/ matemática], entonces la tercera bola es [matemática] 11 [ /mates]. Finalmente, restamos [matemáticas] 48- \ binom {10} {2} [/ matemáticas] y sumamos [matemáticas] 1 [/ matemáticas], para darnos la cuarta bola, [matemáticas] 4 [/ matemáticas].

Por cierto, para evaluar [math] \ displaystyle \ binom {n + 1} {m} [/ math] de manera eficiente dado [math] \ displaystyle \ binom {n} {m} [/ math], simplemente multiplique [math] \ displaystyle \ binom {n} {m} [/ math] por [math] (n + 1) [/ math] y divide entre [math] (n + 1-m) [/ math]. Por ejemplo, [math] \ displaystyle \ binom {40} {20} = 137846528820 [/ math], entonces [math] \ displaystyle \ binom {41} {20} = 137846528820 \ times \ dfrac {41} {41-20 } = 269128937220 [/ matemáticas]. Claramente, esto es mucho más rápido que evaluar [math] \ dfrac {41!} {21! \ Times 20!} [/ Math]. Esto permite que el algoritmo anterior se acelere considerablemente.

Aquí hay una forma de pensar sobre esto. Tiene un conjunto de tamaño 24 y está eligiendo un subconjunto de tamaño 4 de este conjunto. ¿Cómo podemos representar estos subconjuntos para mostrar una biyección de ellos a los números del 1 al 24? Una respuesta es representar los subconjuntos como números binarios.

Permítanme usar valores más pequeños aquí para que sea más fácil de entender. Digamos que hay 5 bolas numeradas del 1 al 5, y desea elegir 2 de ellas. Como sabe, la respuesta es [matemáticas] \ binom {5} {2} = 10 [/ matemáticas].

Aquí se explica cómo crear una biyección entre estos subconjuntos y cadenas binarias de longitud 5.

Digamos que recogió las bolas {3, 5}. La forma de representar esto como una cadena binaria de longitud 5 es primero enumerar los números del 1 al 5. Luego, poner un 0 debajo del número si no está en su subconjunto y poner un 1 debajo del número si está en el subconjunto.

Así es como se vería para el subconjunto {3, 5}:

1 2 3 4 5

0 0 1 0 1 (corresponde a {3, 5})

¿Qué tal el subconjunto {1, 4}? Elegiría la cadena binaria con 1 debajo del 1 y 4 y 0 en cualquier otro lugar:

1 2 3 4 5

1 0 0 1 0 (corresponde a {1, 4})

Tenga en cuenta que, dado que se trata de una biyección, puede retroceder. Supongamos que te di:

1 0 0 0 1

¿A qué subconjunto corresponde esto? La respuesta es {1, 5}.

Así que ahora tiene una biyección de los subconjuntos a cadenas binarias de longitud 5 que tienen exactamente dos 1 en ellas. Esta es una mejor biyección que un mapeo de los números del 1 al 10, porque es fácil retroceder.

——–

Si se vio obligado a asignar del 1 al 10, solo enumere estas cadenas binarias en el orden de menor a mayor:

Número de cadena binaria

00011 1

00101 2

00110 3

01000 4

01001 5

etc.

——–

Por cierto, esta es una buena manera para que las computadoras representen subconjuntos de un conjunto. Utiliza solo 0 y 1 y puede encontrar rápidamente la unión y la intersección, así como otras operaciones en conjuntos.

Si ya puede encontrar todas las combinaciones para una lista “n elegir n”, con un orden importante y no se permite la repetición (que es lo que supongo), entonces no debería ser demasiado difícil. Simplemente encuentre cada combinación de bolas, donde el orden no es importante, para 24 elija 4. Luego, encuentre cada permutación de cada una de esas combinaciones. Después de eso, puede hacer una gran lista de cada permutación que haya encontrado. Luego, clasifique esa gran lista de manera “alfabética” y numere cada entrada. Entonces, para un conjunto de permutaciones “3 elige 2” en el conjunto {1,2,3}, obtendrás esto:

1: {a, b}
2: {a, c}
3: {b, a}
4: {b, c}
5: {c, a}
6: {c, b}

More Interesting

Cómo construir una computadora fuera del agua, y cómo ayuda esto con Navier-Stokes

Con la inmensa potencia de procesamiento en las computadoras actuales, ¿no podemos recurrir al sistema decimal para la informática?

¿Por qué los signos de división y multiplicación generalmente no están estandarizados a diferencia de los signos de suma y resta?

¿Cuál es la base matemática necesaria para la programación competitiva?

¿Qué tan probable es que las computadoras alienígenas se basen en algo equivalente a un UTM?

¿Por qué escribimos A = IA para operaciones de fila y A = AI para operación de columna para encontrar el inverso de una matriz?

Cómo escribir un programa para encontrar el MCD entre dos números en C ++

¿Cómo es tomar CS 221 (Inteligencia Artificial) en Stanford?

¿Los problemas informáticos de tipo nQueens tienen aplicaciones en física, en particular en la teoría de la materia condensada?

¿Es justo decir que las matemáticas, la informática y la programación se encuentran en la intersección de todas las materias?

Cómo calcular la varianza esperada en el tiempo (t) dada una deriva y volatilidad conocidas

¿Necesito matemáticas para programar?

¿Cómo sabe la CPU que estamos usando el complemento de uno o el complemento de dos para representar números negativos?

¿Existe un equivalente al tono perfecto en matemáticas / programación de computadoras? ¿Un atributo que se considera que no se puede aprender pero que es invaluable si lo posee?

¿Qué matemática puede o no puede hacer una computadora?