Genera il minor numero di biglietti della lotteria da giocare per avere almeno N buoni numeri


11

Questo è un argomento matematico piuttosto complesso ma molto interessante (noto come "problema di copertura" ),

E vorrei il tuo aiuto per la sua attuazione.

Immagina un gioco della lotteria, in cui ogni biglietto deve scegliere 5 numeri casuali in un set di 50 numeri (da 1 a 50).

È abbastanza facile conoscere la probabilità di un biglietto vincente o la probabilità di avere 1, 2, 3 o 4 buoni numeri.

È anche abbastanza facile "generare" tutti i biglietti che hanno 1, 2, 3, 4 buoni numeri.

La mia domanda (e la sfida del codice) è correlata a questo, ma leggermente diversa:

Voglio comprare alcuni biglietti della lotteria (il minor numero possibile), ad esempio almeno uno dei miei biglietti ha 3 buoni numeri.

Sfida

Il tuo obiettivo è implementare una soluzione generica (come un programma o solo una funzione), come questa, in qualsiasi lingua:

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

Per l'esempio sopra, si dovrebbe semplicemente chiamare:

min_lottery_tickets(50, 5, 3)

e il programma genererà il minor numero di biglietti da giocare per raggiungere questo obiettivo.


Esempio:

 min_lottery_tickets(10, 5, 2)

produrrebbe 7 ticket, come quelli:

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

perché tali biglietti sono sufficienti per coprire qualsiasi coppia di numeri da 1 a 10.


Produzione

Testo, una riga per biglietto, tabulazioni o spazi tra i numeri


chi vince

Vince il programma più efficiente (ovvero il programma che genera il minor numero di ticket per i parametri sopra indicati):

min_lottery_tickets(50, 5, 3)


Grazie!



4
Questa domanda necessita di vari chiarimenti. Stai cercando un programma, una funzione o uno dei due? Il formato di output è importante? I numeri devono essere indicizzati da 1 o potrebbero essere indicizzati da 0? E qual è la condizione vincente oggettiva?
Peter Taylor,

3
@xem questo appartiene quasi a Math SE allora. Dove probabilmente ti dimostreranno che i numeri non sono a tuo favore (anche se esiste un numero di jackpot per cui vale la pena acquistare i biglietti)
Cruncher,

2
Qual è un buon numero?
DavidC,

2
Sono abbastanza sicuro che è dimostrabile che perderai un sacco di soldi se effettivamente vai a comprare i biglietti emessi da un tale programma.
Michael Hampton,

Risposte:


1

So che non è ottimale , ma ecco il codice in 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);
        }
    }
}

Alcuni risultati di esempio:

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

altro:

> 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 ]

altro:

> 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 ]

1
Il tuo min_lottery_tickets(10, 5, 2)genera molte più soluzioni rispetto agli OP.
Groo,

Conosco @Groo, ho detto che sapevo che non era ottimale, ma questa era la prima versione funzionante che avevo;) Qualche suggerimento su come rimuovere i risultati "ridondanti"?
Greuze,

Ciao Groo, Ciao Greuze, grazie mille per questo primo tentativo. Hai un punteggio di 21 (perché hai generato 21 biglietti per (10,5,2)). Tuttavia, non so come rimuovere i risultati ridondanti, ecco perché ho creato questo argomento. Mi sto ancora chiedendo quale sia il miglior algoritmo per fare questo lavoro.
xem,

Ecco alcune buone letture sull'argomento: (1) dip.sun.ac.za/~vuuren/papers/lotery_artikel1oud.pdf , (2) goo.gl/Ex7Woa , (3) google.fr/…
xem

1
È un problema NP completo, quindi temo non ci sia soluzione magica. Dobbiamo "forzare la forza" il calcolo di tutti i possibili biglietti e l'eliminazione di coloro che sono ridondanti confrontando ciascuno dei suoi gruppi di numeri con tutti gli altri biglietti. Ciò richiederebbe un tempo esponenziale.
xem,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.