Lottery algorithm - PHP math seems good, but is the function valid?

I want to do a custom lottery extraction to motivate users to participate in an online experiment. Rules:

  • 10% to get $ 10
  • 1% chance to get $ 50
  • 0.1% chance to get $ 500

A lottery is a PHP function that is called once and returns a prize (0, 10, 50 or 500). I created the function below, and after 70,000 test statistics:

  • 9.11% for $ 10
  • .91% for $ 50
  • .01% for $ 500

Should I worry about the algorithm? Is there a better way to create a good chance distribution than 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; } 

Thanks for helping the newbie!

+6
source share
2 answers

You have four results with given probabilities:

  • 0.1% chance to win $ 500.
  • 1% chance to win $ 500.
  • 10% chance to win $ 500.

The fourth result - without a win - is 100% minus the sum of the other three results, namely 88.9%.

Marc Gabriel explained why your source code was disabled: by encouraging 10% of people who won winners of $ 10 to $ 50, you take them out of a pool of $ 10, which will be only 9% of all people.

Pham Trung contributed to a solution that still attracts winners of higher amounts from the non-winners pool and adjusts the probabilities. This is an acceptable solution, but the easiest solution is in my turn to call the random number generator only once.

This decision also reflects the best analogy with tickets: you place 10,000 tickets in a box. 1000 tickets from 1 to 1000 win 10 dollars. 100 tickets from 1,001 to 1,100 win $ 50. Ten tickets from 1101 to 1110 won $ 500. All 8890 tickets from 1111 win nothing:

 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; } 

In this code, tickets have only the number written on them. You pick one. Then you check to see if the ticket number is $ 10. If not, you are checking the same ticket for a $ 50 bet. There is really only one random action.

(I used the zero-based random number function in Javascript instead of PHP mt_rand , but I think the solution is clear.)

+2
source

This is because the true odds are everyone in your code:

$ 10 - 0.1*0.9 = 9%

$ 50 - 0.1*0.1*0.9 = 0.9%

$ 500 - 0.1*0.1*0.1 = 0.1%


This is not due to mt_rand() . This is just a statistic problem. Try to run more iterations and you will see that the numbers converge to the numbers above.

As you can see with the above calculations, you will not receive $ 10, having received the right for the first time, you will receive $ 10, having received this right for the first time (10%), and having received the wrong second time (90%).

Following this logic, you can extend the same math for $ 50 (getting it right the first two times, 10% and 10%, then it turned out wrong the third time, 90%) and for $ 500 (you get drills).

With your specific code, the calculations for true probability are the same as above.


See code in accepted answer for correct code with exact probability.

+12
source

Source: https://habr.com/ru/post/987256/


All Articles