Genere la menor cantidad de boletos de lotería para jugar para tener al menos N buenos números

11

Este es un tema matemático bastante complejo pero muy interesante (conocido como "problema de cobertura" ),

Y me gustaría su ayuda para implementarlo.

Imagine un juego de lotería, donde cada boleto debe elegir 5 números aleatorios en un conjunto de 50 números (del 1 al 50).

Es bastante fácil saber la probabilidad de un boleto ganador, o la probabilidad de tener 1, 2, 3 o 4 números buenos.

También es bastante fácil "generar" todas las entradas que tienen 1, 2, 3, 4 números buenos.

Mi pregunta (y el desafío del código) está relacionada con esto, pero ligeramente diferente:

Quiero comprar algunos boletos de lotería (la menor cantidad posible), como que al menos uno de mis boletos tenga 3 números buenos.

Desafío

Su objetivo es implementar una solución genérica (como un programa o simplemente una función), como esta, en cualquier idioma:

// Input: 3 prameters
min_lottery_tickets(total_numbers_to_choose_from, how_many_numbers_to_choose, how_many_good_numbers_i_want)

Para el ejemplo anterior, solo habría que llamar:

min_lottery_tickets(50, 5, 3)

y el programa generará el conjunto más pequeño de boletos para lograr este objetivo.


Ejemplo:

 min_lottery_tickets(10, 5, 2)

generaría 7 tickets, como esos:

1   2   3   4   5
5   6   7   8   9
10  1   2   6   7
10  3   4   8   9
3   4   6   7   8
1   2   3   8   9
1   4   9   5   10

porque tales boletos son suficientes para cubrir cualquier par de números del 1 al 10.


Salida

Texto, una línea por boleto, tabulaciones o espacios entre números


quién gana

El programa más eficiente gana (es decir, el programa que genera la menor cantidad de tickets para los parámetros anteriores):

min_lottery_tickets(50, 5, 3)


¡Gracias!

xem
fuente
Relacionados .
Peter Taylor
44
Esta pregunta necesita varias aclaraciones. ¿Estás buscando un programa, una función o cualquiera? ¿Importa el formato de salida? ¿Deben indexarse ​​los números desde 1, o podrían indexarse ​​desde 0? ¿Y cuál es la condición objetiva para ganar?
Peter Taylor
3
@xem esto casi pertenece a Math SE entonces. Donde probablemente le demostrarán que los números no están a su favor (aunque existe algún número de premio mayor, vale la pena comprar boletos)
Cruncher
2
¿Qué es un buen número?
DavidC
2
Estoy bastante seguro de que es comprobable que perderá mucho dinero si realmente compra los boletos emitidos por dicho programa.
Michael Hampton

Respuestas:

1

Sé que no es óptimo , pero aquí está el código en node.js:

function min_lottery_tickets(total_numbers_to_choose_from, how_many_numbers_to_choose, how_many_good_numbers_i_want) {
    c(function(result) {
        var other = result[result.length - 1];
        while (result.length < how_many_numbers_to_choose) {
            other++;
            var already = false;
            for (var i = 0; i < result.length; i++) {
                if (other === result[i]) {
                    already = true;
                    break;
                }
            }
            if (!already) {
                result.push(other);            
            }
        }
        if (other <= total_numbers_to_choose_from) {
            // Print results
            console.log(result);
        }
    }, total_numbers_to_choose_from, how_many_good_numbers_i_want);
}

function c(next, total_numbers, length, start, results) {
    if (!start) start = 1;
    if (!results) results = [];

    for (var i = start; i <= total_numbers + 1 - length; i++) {
        var resultsNew = results.slice(0);
        resultsNew.push(i);
        if (length > 1) {
            c(next, total_numbers, length - 1, i + 1, resultsNew);
        } else {
            next(resultsNew);
        }
    }
}

Algunos resultados de ejemplo:

> min_lottery_tickets(5, 3, 2)
[ 1, 2, 3 ]
[ 1, 3, 4 ]
[ 1, 4, 5 ]
[ 2, 3, 4 ]
[ 2, 4, 5 ]
[ 3, 4, 5 ]

otro:

> min_lottery_tickets(10, 5, 2)
[ 1, 2, 3, 4, 5 ]
[ 1, 3, 4, 5, 6 ]
[ 1, 4, 5, 6, 7 ]
[ 1, 5, 6, 7, 8 ]
[ 1, 6, 7, 8, 9 ]
[ 1, 7, 8, 9, 10 ]
[ 2, 3, 4, 5, 6 ]
[ 2, 4, 5, 6, 7 ]
[ 2, 5, 6, 7, 8 ]
[ 2, 6, 7, 8, 9 ]
[ 2, 7, 8, 9, 10 ]
[ 3, 4, 5, 6, 7 ]
[ 3, 5, 6, 7, 8 ]
[ 3, 6, 7, 8, 9 ]
[ 3, 7, 8, 9, 10 ]
[ 4, 5, 6, 7, 8 ]
[ 4, 6, 7, 8, 9 ]
[ 4, 7, 8, 9, 10 ]
[ 5, 6, 7, 8, 9 ]
[ 5, 7, 8, 9, 10 ]
[ 6, 7, 8, 9, 10 ]

otro:

> min_lottery_tickets(10, 5, 3)
[ 1, 2, 3, 4, 5 ]
[ 1, 2, 4, 5, 6 ]
[ 1, 2, 5, 6, 7 ]
[ 1, 2, 6, 7, 8 ]
[ 1, 2, 7, 8, 9 ]
[ 1, 2, 8, 9, 10 ]
[ 1, 3, 4, 5, 6 ]
[ 1, 3, 5, 6, 7 ]
[ 1, 3, 6, 7, 8 ]
[ 1, 3, 7, 8, 9 ]
[ 1, 3, 8, 9, 10 ]
[ 1, 4, 5, 6, 7 ]
[ 1, 4, 6, 7, 8 ]
[ 1, 4, 7, 8, 9 ]
[ 1, 4, 8, 9, 10 ]
[ 1, 5, 6, 7, 8 ]
[ 1, 5, 7, 8, 9 ]
[ 1, 5, 8, 9, 10 ]
[ 1, 6, 7, 8, 9 ]
[ 1, 6, 8, 9, 10 ]
[ 1, 7, 8, 9, 10 ]
[ 2, 3, 4, 5, 6 ]
[ 2, 3, 5, 6, 7 ]
[ 2, 3, 6, 7, 8 ]
[ 2, 3, 7, 8, 9 ]
[ 2, 3, 8, 9, 10 ]
[ 2, 4, 5, 6, 7 ]
[ 2, 4, 6, 7, 8 ]
[ 2, 4, 7, 8, 9 ]
[ 2, 4, 8, 9, 10 ]
[ 2, 5, 6, 7, 8 ]
[ 2, 5, 7, 8, 9 ]
[ 2, 5, 8, 9, 10 ]
[ 2, 6, 7, 8, 9 ]
[ 2, 6, 8, 9, 10 ]
[ 2, 7, 8, 9, 10 ]
[ 3, 4, 5, 6, 7 ]
[ 3, 4, 6, 7, 8 ]
[ 3, 4, 7, 8, 9 ]
[ 3, 4, 8, 9, 10 ]
[ 3, 5, 6, 7, 8 ]
[ 3, 5, 7, 8, 9 ]
[ 3, 5, 8, 9, 10 ]
[ 3, 6, 7, 8, 9 ]
[ 3, 6, 8, 9, 10 ]
[ 3, 7, 8, 9, 10 ]
[ 4, 5, 6, 7, 8 ]
[ 4, 5, 7, 8, 9 ]
[ 4, 5, 8, 9, 10 ]
[ 4, 6, 7, 8, 9 ]
[ 4, 6, 8, 9, 10 ]
[ 4, 7, 8, 9, 10 ]
[ 5, 6, 7, 8, 9 ]
[ 5, 6, 8, 9, 10 ]
[ 5, 7, 8, 9, 10 ]
[ 6, 7, 8, 9, 10 ]
greuze
fuente
1
Tu min_lottery_tickets(10, 5, 2)genera muchas más soluciones que los OP.
Groo
Lo sé @Groo, dije que sabía que no era óptimo, pero esta era la primera versión que tenía;) ¿Alguna sugerencia sobre cómo eliminar resultados "redundantes"?
greuze
Hola Groo, hola greuze, muchas gracias por este primer intento. Tiene una puntuación de 21 (porque generó 21 tickets para (10,5,2)). Sin embargo, no sé cómo eliminar los resultados redundantes, por eso creé este tema. Todavía me pregunto cuál es el mejor algoritmo para hacer este trabajo.
xem
Aquí hay algunas buenas lecturas sobre el tema: (1) dip.sun.ac.za/~vuuren/papers/lotery_artikel1oud.pdf , (2) goo.gl/Ex7Woa , (3) google.fr/…
xem
1
Es un problema de NP completo, así que me temo que no hay una solución mágica. Tenemos que "forzar" el cálculo de todos los tickets posibles y la eliminación de aquellos que son redundantes al comparar cada uno de sus grupos de números con todos los demás tickets. Eso llevaría un tiempo exponencial.
xem