We can generate psedorandom numbers by generating a sequence of random-seeming numbers. This is what Python's random.random()
does. One way to generate pseudo-random numbers is to use a linear congruential generator: we repeatedly compute x
using
x = (a*x+b) % m
This will generate random seeming numbers:
a = 1664525
b = 1013904223
m = 2**32 - 1
x = 1
for i in range(10):
x = (a*x+b) % m
print(x)
1015568748 1586399053 170058213 3046353778 158472183 2212922578 3231609888 2113058113 157256853 2195350273
If we want numbers in the range 0..1, we can divide by m
:
for i in range(10):
x = (a*x+b) % m
print(x/m)
0.5629632420751646 0.6265831362983638 0.5310150069489644 0.990509697932403 0.39101890600077316 0.9805789098564021 0.34599670054064985 0.39403539812053445 0.00712455553168537 0.2368643514897824
Usually, when generating pseudo-random numbers this way, we'll only take the middle digits of x. Note that if we are not careful, the last digit can seem non-random: for example, we m is even and we start with an x = 1 and a even, we'll always get an odd last digit:
a = 1664524
b = 0
m = 2**32
x = 1
for i in range(10):
x = (a*x+b) % m
print(x)
1664524 386240656 1777084096 3611447552 1818348544 4158492672 4123181056 3718316032 2307653632 982515712
The seed determines where we start the sequence of pseudo-random numbers. Above, we started with x = 1.
If we want consistent output across runs, we'll set the seed to some set number.
If we want to get a different output every time, we can set the seed to time.time() -- the epoch time we get from the clock. (So you can use random.seed(time.time())
).
Let's now write our own random module. We'll name it myrandom
, and we'll write it so that we can use it just like random
:
# myrandom.py
def myrandom():
global x
x = (a*x+b) % m
return x/m
def seed(s):
global x
x = (a*x+b) % m
def initialize():
global a, b, n, x
a = 1664525
b = 1013904223
m = 2**32 - 1
x = 1
initialize() # call initialize outside the main block so that the seed as well as the constants are set
We can now use this code in another file:
import myrandom
import time
if __name__ == '__main__':
# Will print the same sequence every time:
myrandom.seed(0)
print(myrandom.myrandom())
print(myrandom.myrandom())
print(myrandom.myrandom())
# The same sequence as above again
myrandom.seed(0)
print(myrandom.myrandom())
print(myrandom.myrandom())
print(myrandom.myrandom())
# A different sequence every run, since we are seeding using time.time()
myrandom.seed(int(time.time())
print(myrandom.myrandom())
print(myrandom.myrandom())
print(myrandom.myrandom())