2015-05-15 7 views
6

Chcę dokonać niestandardowej ekstrakcji loterii, aby zmotywować użytkowników do udziału w eksperymencie online. Zasady są:Algorytm loterii - PHP - matematyka wydaje się dobra, ale czy funkcja jest ważna?

  • 10%, aby uzyskać 10 dolarów
  • 1% szans na zdobycie 50 dolarów
  • 0,1% szans na zdobycie 500 $

loterii jest funkcja PHP, który pobiera zadzwonił raz i zwrócił nagrodę (0, 10, 50 lub 500). Stworzyłem funkcję poniżej, a po 70 000 badań statystyki to:

  • 9,11% do 10 $
  • 0,91% do 50 $
  • 0,01% do 500 $

Czy powinienem się martwić o algorytm? Czy istnieje lepszy sposób na stworzenie dobrego rozkładu szans niż mt_rand?

function lottery() { 
    // winnings before extraction 
    $win=0; 

    // choose a winning number between 1 and 10 
    $target=mt_rand(1,10); 

    // make three independent extractions, each with 1/10 probability 
    if (mt_rand(1,10) == $target) { 
    // if first extraction is the winning number -> prize=10 
    // probability: 1/10 
    $win=10; 

    if (mt_rand(1,10) == $target) { 
     // if second extraction is ALSO the winning number -> prize=50 
     // probability: 1/10 * 1/10 
     $win=50; 

     if (mt_rand(1,10) == $target) { 
      // if third extraction is ALSO the winning number -> prize=500 
      // probability: 1/10 * 1/10 * 1/10 
      $win=500; 
     } 
    } 
    } 
    // return the prize 
    return $win; 
} 

Dziękujemy za pomoc początkującym!

+1

Jeśli spojrzeć na 10 dolarów ceny to odchylenie od średniej wynosi 0,89, co jest o wiele więcej niż standardowe odchylenie (sqrt (0,1 * 0,9)/sqrt (70000) ~ = 0,0011). Więc coś jest (prawdopodobnie) dzieje się tutaj źle, chociaż nie jestem w stanie tego zauważyć. – vib

+1

Nawiasem mówiąc, wartość docelowa nie musi być losowa. Powinien również działać test '10 * mt_rand()

+0

Jeszcze innym sposobem jest narysowanie w zakresie '(0,999)' i sprawdzenie dla '0 -', '00-' lub '000'. –

Odpowiedz

2

Masz cztery wyniki z podanych prawdopodobieństw:

  • 0,1% prawdopodobieństwo, aby wygrać $ 500 mm.
  • 1% prawdopodobieństwa wygrania 500 $.
  • 10% prawdopodobieństwa wygrania 500 $.

Czwarty wynik - brak wygranej - wynosi 100% minus suma pozostałych trzech wyników, a mianowicie 88,9%.

Mark Gabriel wyjaśnił, dlaczego Twój początkowy kod był wyłączony: promując 10% osób, które wygrały od 10 do 50 zwycięzców, zabierasz je z puli 10 $ zwycięzcy, która będzie tylko 9% wszystkich ludzi .

Pham Trung przyczyniło się do rozwiązania problemu, dzięki któremu zwycięzcy wygrywają większe kwoty z puli dotychczas nieuznanych zwycięzców i dostosowują prawdopodobieństwo. Jest to praktyczne rozwiązanie, ale najłatwiejsze rozwiązanie polega na tym, że mogę jednorazowo wywołać generator liczb losowych.

To rozwiązanie najlepiej odzwierciedla analogię biletów: umieszczasz 10.000 biletów w pudełku. 1000 biletów od 1 do 1000 wygrywa 10 $. 100 biletów od 1001 do 1100 wygrywa 50 $. Dziesięć biletów od 1101 do 1110 wygrywa 500 $. Wszystkie bilety na 8890 od 1111 na nic nie wygrywają:

function lottery() { 
    var pick = Math.floor(10000 * Math.random()); 
       // random number in the range [0, 10000). 

    if (pick < 1000) return 10; 
    if (pick < 1100) return 50; 
    if (pick < 1110) return 500; 

    return 0; 
} 

W tym kodzie bilety mają tylko ich numer napisany na nich. Wybierz jedną. Następnie sprawdzasz, czy numer biletu kwalifikuje się do 10 $. Jeśli nie, sprawdź ten ten sam bilet, czy może postawić wygraną 50 $. W grę wchodzi naprawdę tylko jedna akcja losowa.

(Użyłem od zera funkcji liczb losowych w JavaScript zamiast PHP mt_rand, ale myślę, że roztwór jest przezroczysty).

+0

Dziękujemy! Nie doceniłem tego problemu. Mark Gabriel wyraźnie wskazał na wadę, ale masz - moim zdaniem - najłatwiejsze rozwiązanie. Zmieniłem twój kod na PHP i otrzymałem wyniki dla symulacji 100000: (10 $ = 10,084; 50 $ = 1,015; 500 $ = 0,1) (10 $ = 9,901; 50 $ = 1; 500 $ = 0,099). Pójdę z twoim rozwiązaniem. – verjas

12

To dlatego, że prawdziwe szanse na uzyskanie każdy w kodzie są:

$ 10 - 0.1*0.9 = 9%

50 $ - 0.1*0.1*0.9 = 0,9%

$ 500 - 0.1*0.1*0.1 = 0.1%


Nie jest to spowodowane mt_rand(). To tylko problem statystyczny. Spróbuj uruchomić więcej powtórzeń, a zobaczysz, że liczby zbiegają się do powyższych liczb.

Jak widać z powyższych obliczeń, nie otrzymasz 10 $, otrzymując za pierwszym razem prawidłowy wynik, dostajesz 10 $, uzyskując prawo za pierwszym razem (10%), I ponosząc błąd po raz drugi (90%).

Zgodnie z tą logiką, możesz przedłużyć tę samą matematykę o 50 $ (otrzymujesz to prawo od pierwszych dwóch razy, 10% i 10%, THEN źle się po raz trzeci, 90%) i za 500 $ (dostajesz wiertarka).

Przy pomocy twojego kodu, obliczenia dla prawdziwego prawdopodobieństwa są jak powyżej.


Zobacz kod w zaakceptowanej odpowiedzi dla poprawnego kodu z dokładnymi prawdopodobieństwami.

+0

Wyjaśnienie byłoby mile widziane. –

+0

Dlaczego upadek? To matematyka, chłopaki. -- UPS przepraszam. @ YvesDaoust, byłem w trakcie edycji odpowiedzi. –

+0

Tak, pobierz teraz, wznowione, dobrze zrobione! –

Powiązane problemy