Python Programming - IX. On Randomness
-
Upload
engr-ranel-padon -
Category
Technology
-
view
1.255 -
download
1
description
Transcript of Python Programming - IX. On Randomness
Engr. RANEL O. PADONIX. ON RANDOMNESS
PYTHON PROGRAMMING TOPICS
I•Introduction to Python Programming
II•Python Basics
III•Controlling the Program Flow
IV•Program Components: Functions, Classes, Packages, and Modules
V•Sequences (List and Tuples), and Dictionaries
VI•Object-Based Programming: Classes and Objects
VII•Customizing Classes and Operator Overloading
VIII•Object-Oriented Programming: Inheritance and Polymorphism
IX•Randomization Algorithms
X•Exception Handling and Assertions
XI•String Manipulation and Regular Expressions
XII•File Handling and Processing
XIII•GUI Programming Using Tkinter
RANEL O. PADON
ON RANDOMNESS
RANEL O. PADON
ON RANDOMNESS
ON RANDOMNESS
Randomization Algorithms
* Random numbers are used for testing the performance of programs,
creating scientific simulations, and so on.
* A pseudorandom number generator (PRNG) is an algorithm for
generating a sequence of numbers that approximates the properties
of random numbers.
* The sequence is not truly random in that it is completely
determined by a relatively small set of initial values (random seed)
Early Algorithm
Middle-Square Method
* take any number, square it, remove the middle digits of the
resulting number as the "random number", then use that number as
the seed for the next iteration.
* squaring the number "1111" yields "1234321", which can be written
as "01234321", an 8-digit number being the square of a 4-digit
number. This gives "2343" as the "random" number. Repeating this
procedure gives "4896" as the next result, and so on.
ON RANDOMNESS Randomization Algorithms
1.) Blum Blum Shub (cryptographically sound, but slow)
2.) Mersenne Twister
- fast with good statistical properties,
- used when cyptography is not an issue
- used in Python
3.) Linear Congruential Generator
- commonly-used in compilers
and many, many others
ON RANDOMNESS Randomization Algorithms
ON RANDOMNESS Randomization Algorithms
2.) Mersenne Twister Algorithm
is based on a matrix linear recurrence over a finite binary field
provides for fast generation of very high-quality pseudorandom
numbers, having been designed specifically to rectify many of the
flaws found in older algorithms.
used in PHP, Ruby and Python
name derives from the fact that period length is chosen to be a
Mersenne prime
ON RANDOMNESS Mersenne Twister Algorithm
2.) Mersenne Twister Algorithm
It has a very long period of 219937 − 1. While a long period is
not a guarantee of quality in a random number generator, short
periods (such as the 232 common in many software packages)
can be problematic.
It is k-distributed to 32-bit accuracy for every 1 ≤ k ≤ 623
It passes numerous tests for statistical randomness, including the
Diehard tests. It passes most, but not all, of the even more
stringent TestU01 Crush randomness tests.
# Create a length 624 list to store the state of the generator
MT = [0 for i in xrange(624)]
index = 0
# To get last 32 bits
bitmask_1 = (2 ** 32) - 1
# To get 32. bit
bitmask_2 = 2 ** 31
# To get last 31 bits
bitmask_3 = (2 ** 31) - 1
2.) Mersenne Twister Algorithm
(as used in the random module of Python)
ON RANDOMNESS Mersenne Twister Algorithm
def initialize_generator(seed):
"Initialize the generator from a seed"
global MT
global bitmask_1
MT[0] = seed
for i in xrange(1,624):
MT[i] = ((1812433253 * MT[i-1]) ^ ((MT[i-1] >> 30) + i)) &
bitmask_1
ON RANDOMNESS Mersenne Twister Algorithm
2.) Mersenne Twister Algorithm
def extract_number():
""“ Extract a tempered pseudorandom number based on the index-
th value, calling generate_numbers() every 624 numbers ""“
global index
global MT
if index == 0:
generate_numbers()
y = MT[index]
y ^= y >> 11
y ^= (y << 7) & 2636928640
y ^= (y << 15) & 4022730752
y ^= y >> 18
index = (index + 1) % 624
return y
ON RANDOMNESS Mersenne Twister Algorithm
def generate_numbers():
"Generate an array of 624 untempered numbers"
global MT
for i in xrange(624):
y = (MT[i] & bitmask_2) + (MT[(i + 1 ) % 624] & bitmask_3)
MT[i] = MT[(i + 397) % 624] ^ (y >> 1)
if y % 2 != 0:
MT[i] ^= 2567483615
if __name__ == "__main__":
from datetime import datetime
now = datetime.now()
initialize_generator(now.microsecond)
for i in xrange(100):
"Print 100 random numbers as an example"
print extract_number()
ON RANDOMNESS Mersenne Twister Algorithm
ON RANDOMNESS Linear Congruential Generator
3.) Linear Congruential Generator
represents one of the oldest and best-known pseudorandom number
generator algorithms.
the theory behind them is easy to understand, and they are easily
implemented and fast.
3.) Linear Congruential Generator
ON RANDOMNESS Linear Congruential Generator
3.) Linear Congruential Generator
The basic idea is to multiply the last number with a factor a, add a
constant c and then modulate it by m.
Xn+1 = (aXn + c) mod m.
where X0 is the seed.
ON RANDOMNESS Randomization Algorithms
Random Seed
* a number (or vector) used to initialize a pseudorandom number
generator
* crucial in the field of computer security.
* having the seed will allow one to obtain the secret encryption key
in a pseudorandomly generated encryption values
ON RANDOMNESS Random Seed
Random Seed
* two or more systems using matching pseudorandom number
algorithms and matching seeds can generate matching sequences of
non-repeating numbers which can be used to synchronize remote
systems, such as GPS satellites and receivers.
ON RANDOMNESS Random Seed
a = 3
c = 9
m = 16
xi = 0
def seed(x):
global xi
xi = x
def rng():
global xi
xi = (a*xi + c) % m
return xi
for i in range(10):
print rng()
ON RANDOMNESS Linear Congruential Generator
Random
Number
Generator
LCG (Standard Parameters)
Good One
ON RANDOMNESS Linear Congruential Generator
a = 25214903917
c = 11
m = 2**48
xi = 1000
def seed(x):
global xi
xi = x
def rng():
global xi
xi = (a*xi + c) % m
return xi
def rng_bounded(low, high):
return low + rng()%(high - low+1)
for i in range(10):
rng_bounded(1, 10)
Using
java.util.Random
parameters
ON RANDOMNESS Linear Congruential Generator
MINSTD by Park & Miller (1988)
known as the Minimal Standard Random number generator
a very good set of parameters for LCG:
m = 231 − 1 = 2,147,483,647 (a Mersenne prime M31)
a = 75 = 16,807 (a primitive root modulo M31)
c = 0
often the generator that used for the built in random number function in
compilers and other software packages.
used in Apple CarbonLib, a procedural API for developing Mac OS X
applications
ON RANDOMNESS Minimal Standard
a = 7**5
c = 0
m = 2**31 - 1
xi = 1000
def seed(x):
global xi
xi = x
def rng():
global xi
xi = (a*xi + c) % m
return xi
def rng_bounded(low, high):
return low + rng() % (high - low+1)
for i in range(10):
rng_bounded(1, 2)
Using
MINSTD
parameters
ON RANDOMNESS Linear Congruential Generator
from __ future__ import division
if __name__ == '__main__':
main()
a = 7**5
c = 0
m = 2**31 - 1
xi = 1000
def seed(x):
global xi
xi = x
def rng():
global xi
xi = (a*xi + c) % m
return xi
ON RANDOMNESS Linear Congruential Generator
Tossing 1 Coin
using LCG MINSTD
(1 million times)
def rng_bounded(low, high):
return low + rng() % (high - low+1)
(heads, tails, count) = (0, 0, 0)
for i in range (1, 1000001):
count += 1
coin rng_bounded(1,2)
if coin == 1:
heads += 1
else:
tails += 1
ON RANDOMNESS Linear Congruential Generator
Tossing 1 Coin
using LCG MINSTD
(1 million times)
print "heads is ", heads/count
print "tails is ", tails/countTossing 1 Coin
using LCG MINSTD
(1 million times)
ON RANDOMNESS Linear Congruential Generator
from __ future__ import division
import random
if __name__ == '__main__':
main()
(heads, tails, count) = (0, 0, 0)
random.seed(1000)
for i in range (1,1000001):
count +=1
coin = random.randrange(1,3)
ON RANDOMNESS Linear Congruential Generator
Tossing 1 Coin
using Python randrange()
(1 million times)
if coin == 1:
heads += 1
else:
tails += 1
print "heads is ", heads/count
print "tails is ", tails/count
ON RANDOMNESS Linear Congruential Generator
Tossing 1 Coin
using Python randrange()
(1 million times)
from __ future__ import division
if __name__ == '__main__':
main()
a = 7**5
c = 0
m = 2**31 - 1
xi = 1000
def seed(x):
global xi
xi = x
def rng():
global xi
xi = (a*xi + c) % m
return xi
ON RANDOMNESS Linear Congruential Generator
Tossing 2 Coins
using LCG MINSTD
(1 million times)
def rng_bounded(low, high):
return low + rng() % (high - low+1)
(heads, tails, combo, count) = (0, 0, 0, 0)
for i in range (1,1000001):
count += 1
coin1 = rng_bounded(1,2)
coin2 = rng_bounded(1,2)
sum = coin1 + coin2
if sum == 2:
heads += 1
elif sum == 4:
tails += 1
else:
combo += 1
ON RANDOMNESS Linear Congruential Generator
Tossing 2 Coins
using LCG MINSTD
(1 million times)
print "head is ", heads/count
print "tail is ", tails/count
print "combo is ", combo/count
Tossing 2 Coins
using LCG MINSTD
(1 million times)
ON RANDOMNESS Linear Congruential Generator
from __ future__ import division
import random
if __name__ == '__main__':
main()
(heads, tails, combo, count) = (0, 0, 0, 0)
random.seed(1000)
for i in range (1,1000001):
count +=1
coin1 = random.randrange(1,3)
coin2 = random.randrange(1,3)
sum = coin1 + coin2
ON RANDOMNESS Linear Congruential Generator
Tossing 2 Coins
using Python randrange()
(1 million times)
if sum == 2:
heads += 1
elif sum == 4:
tails += 1
else:
combo += 1
print "head is ", heads/count
print "tail is ", tails/count
print "combo is ", combo/count
ON RANDOMNESS Linear Congruential Generator
Tossing 2 Coins
using Python randrange()
(1 million times)
ON RANDOMNESS Results Summary
Tossing 1 Coin using LCG MINSTD vs Python randrange() (1 million times)
Tossing 2 Coins using LCG MINSTD vs Python randrange() (1 million times)
A l m o s t S i m i l a r Re s u l t s
ON RANDOMNESS Linear Congruential Generator
Tossing 1 Coin using LCG MINSTD (1000 times)
More Elegant Way (Using List)
from __future__ import division
if __name__ == '__main__':
main()
xi = 1000
def seed(x):
global xi
xi = x
def rng(a=7**5, c=0, m = 2**31 - 1):
global xi
xi = (a*xi + c) % m
return xi
def rng_bounded(low, high):
return low + rng() % (high - low+1)
ON RANDOMNESS Linear Congruential Generator
Tossing 2 Coins
using LCG MINSTD
(1 million times)
More Elegant Way
(Using List)
tosses = []
for i in range (1, 1000001):
tosses += [rngNiRanie(1, 2) + rngNiRanie(1, 2)]
print "heads count is ", tosses.count(2) / len(tosses)
print "tails count is ", tosses.count(4) / len(tosses)
print "combo count is ", tosses.count(3) / len(tosses)
ON RANDOMNESS Linear Congruential Generator
Tossing 2 Coins
using LCG MINSTD
(1 million times)
More Elegant Way
RANEL O. PADON
ON RANDOMNESS
ON RANDOMNESS
a = 25214903917
c = 11
m = 2**48
xi = 1000
def seed(x):
global xi
xi = x
def rng():
global xi
xi = (a*xi + c) % m
return xi
def ranie(lowerBound, upperBound):
#ano laman nito? #
for i in range(10):
ranie(1,10)
REFERENCES
Deitel, Deitel, Liperi, and Wiedermann - Python: How to Program (2001).
Disclaimer: Most of the images/information used here have no proper source citation, and I do
not claim ownership of these either. I don’t want to reinvent the wheel, and I just want to reuse
and reintegrate materials that I think are useful or cool, then present them in another light,
form, or perspective. Moreover, the images/information here are mainly used for
illustration/educational purposes only, in the spirit of openness of data, spreading light, and
empowering people with knowledge.