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.