Wygeneruj najmniej loterii, aby zagrać, aby mieć co najmniej N dobrych liczb

11

Jest to dość złożony, ale bardzo interesujący przedmiot matematyczny (znany jako „problem kryjący” ),

I chciałbym, żebyś pomógł w jego wdrożeniu.

Wyobraź sobie grę loteryjną, w której każdy los musi wybrać 5 liczb losowych z zestawu 50 liczb (od 1 do 50).

Dość łatwo jest poznać prawdopodobieństwo wygranego biletu lub prawdopodobieństwo posiadania 1, 2, 3 lub 4 dobrych liczb.

Bardzo łatwo jest również „wygenerować” wszystkie bilety, które mają 1, 2, 3, 4 dobre liczby.

Moje pytanie (i wyzwanie kodu) jest z tym związane, ale nieco inne:

Chcę kupić losy na loterię (możliwie najmniej), np. Przynajmniej jeden z moich losów ma 3 dobre numery.

Wyzwanie

Twoim celem jest wdrożenie ogólnego rozwiązania (jako programu lub po prostu funkcji), takiego jak to, w dowolnym języku:

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

W powyższym przykładzie wystarczy zadzwonić:

min_lottery_tickets(50, 5, 3)

a program wygeneruje najmniejszy zestaw biletów do gry, aby osiągnąć ten cel.


Przykład:

 min_lottery_tickets(10, 5, 2)

wyświetli 7 biletów, takich jak te:

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

ponieważ takie bilety wystarczą na pokrycie dowolnej pary liczb od 1 do 10.


Wynik

Tekst, jeden wiersz na bilet, tabulacje lub spacje między liczbami


kto wygrywa

Najbardziej wydajny program wygrywa (tzn. Program generujący najmniej biletów dla powyższych parametrów):

min_lottery_tickets(50, 5, 3)


Dzięki!

Xem
źródło
Związane .
Peter Taylor,
4
To pytanie wymaga różnych wyjaśnień. Czy szukasz programu, funkcji lub jednego z nich? Czy format wyjściowy ma znaczenie? Czy liczby muszą być indeksowane od 1, czy też mogą być indeksowane od 0? A jaki jest obiektywny warunek wygranej?
Peter Taylor,
3
@xem to prawie należy wtedy do Math SE. Tam, gdzie prawdopodobnie udowodnią ci, że liczby nie są na twoją korzyść (chociaż istnieje pewna liczba jackpotów, warto kupić bilety)
Cruncher
2
Jaka jest dobra liczba?
DavidC,
2
Jestem prawie pewien, że można udowodnić, że stracisz dużo pieniędzy, jeśli faktycznie kupisz wyjście z biletów przez taki program.
Michael Hampton

Odpowiedzi:

1

Wiem, że to nie jest optymalne , ale oto kod w 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);
        }
    }
}

Niektóre przykładowe wyniki:

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

inny:

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

inny:

> 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
źródło
1
Twój min_lottery_tickets(10, 5, 2)generuje znacznie więcej rozwiązań niż OP.
Groo
Wiem @Groo, powiedziałem, że wiedziałem, że to nie jest optymalne, ale to była pierwsza działająca wersja, którą miałem;) Wszelkie sugestie, jak usunąć „zbędne” wyniki?
greuze
Cześć Groo, Cześć Greuze, wielkie dzięki za pierwszą próbę. Masz wynik 21 (ponieważ wygenerowałeś 21 biletów dla (10,5,2)). Nie wiem jednak, jak usunąć zbędne wyniki, dlatego właśnie stworzyłem ten temat. Nadal zastanawiam się, jak wygląda najlepszy algorytm do wykonania tego zadania.
xem
Oto kilka dobrych odczytów na ten temat: (1) dip.sun.ac.za/~vuuren/papers/lotery_artikel1oud.pdf , (2) goo.gl/Ex7Woa , (3) google.fr/...
xem
1
Jest to problem NP-zupełny, więc obawiam się, że nie ma magicznego rozwiązania. Musimy „brutalnie wykorzystać” obliczenia wszystkich możliwych biletów i wyeliminować tych, którzy są zbędni, porównując każdą z jej grup liczb z pozostałymi biletami. Zajmie to wykładniczy czas.
xem.