Saturday 20 October 2018

Lotto Simulations

I've written about Lotto before in this post (Oz Lotto) and another (Losing at Lotto). The current post is not about probabilities but simulation. How can we use SageMath to simulate a lottery draw? Well as it turns out it's not too difficult.


The key is to use the ZZ.random_element(lowerbound, upperbound+1) function as in the following code. The trick is not to allow duplicate numbers and that is the reason for the inclusion of Set. This function takes our lotto list which might look like this the list [20, 37, 6, 37, 1, 19, 16] and turns it, after the sort, into the ordered set {1, 6, 16, 19, 20, 37}.

Here is the code I developed. I'm really just a tyro at both Python and SageMath so there may well be much better ways to achieve my goals but this is what I came up with:
# Generate a set of numbers for lotto games
# let N represent how many numbers are required in the game
# let G represent the number of games
# let U represent the upper bound of numbers
G=8
N=7
U=40
for i in range(G):
    lotto=[]
    while len(Set(lotto))<N:
        lotto.append(ZZ.random_element(1,U+1))
    print sorted(Set(lotto))
The following is an example of the output:
[11, 23, 27, 30, 37, 38, 40]
[4, 7, 8, 15, 20, 29, 38]
[8, 9, 13, 14, 21, 28, 36]
[7, 11, 15, 21, 28, 33, 40]
[1, 15, 17, 18, 28, 33, 39]
[4, 7, 11, 14, 18, 29, 32]
[1, 10, 12, 16, 21, 31, 33]
[2, 7, 8, 12, 13, 19, 27]
How really random this output is I don't know. I'm sure SageMath has other ways to generate more truly random numbers but this is sufficient for the modest purposes of the exercise.

The code has the added advantage of being able to accommodate "fixed" numbers. For example, let's say we always want the numbers 23 and 32 included in the output. All that needs to be done is to start with lotto = [23, 32] instead of it being an empty list.

For example:
# Generate a set of numbers for lotto games
# let N represent how many numbers are required in the game
# let G represent the number of games
# let U represent the upper bound of numbers
G=8
N=7
U=40
for i in range(G):
    lotto=[23, 32]
    while len(Set(lotto))<N:
        lotto.append(ZZ.random_element(1,U+1))
    print sorted(Set(lotto))
Here an example of the output:
[10, 11, 21, 23, 32, 35, 37]
[5, 6, 17, 23, 31, 32, 39]
[6, 11, 17, 23, 31, 32, 39]
[3, 15, 18, 23, 26, 30, 32]
[2, 12, 13, 23, 27, 28, 32]
[7, 18, 23, 26, 32, 35, 38]
[2, 11, 17, 19, 23, 32, 33]
[3, 16, 23, 26, 27, 31, 32
Not that I expect it will make any difference to my chances of winning but I'll test this out in some coming Lotto games. Oddly enough what got me thinking about generating some random lotto numbers was this article titled JERRY AND MARGE GO LARGE in the Huffington Post. It's about an American couple who exploited a feature in their state's lottery to make millions of dollars. It's quite an interesting story.

As I've been doing I'll include a SageMathCell with the code so that anyone curious can experiment:

No comments:

Post a Comment