Source code for codeviking.random.lcg
import math
from .primitive import PrimitiveRandomNumberGenerator
__all__ = ['LCG','LCG0','LCG1','LCG2']
[docs]class LCG(PrimitiveRandomNumberGenerator):
"""
Linear Congruential Random number Generator.
This is the MINSTD linear congruential random number generator. Under no
circumstances should you pick a, m, q, r without doing some serious research
into random number generation. You *absolutely must* understand these
parameters *and* how to choose them. There are only a handful of known
good combinations. If you choose these parameters carelessly, your RNG
will not work properly.
There are a few subclasses provided that use known good parameters.
Note that the seed must be an integer >= 0. This is different from the
standard MINSTD generator, which requires an integer > 0. Lots of users
seem to like using a seed of zero, so we simply add 1 to the provided
seed.
For more info, see:
Stephen K. Park and Keith W. Miller and Paul K. Stockmeyer (1988).
"Technical Correspondence". Communications of the ACM 36 (7): 105–110.
doi:10.1145/159544.376068
which is available at:
[http://www.firstpr.com.au/dsp/rand31/p105-crawford.pdf]
"""
def __init__(self, a, m, q, r, seed):
super().__init__(m)
self._a, self._m, self._q, self._r = a, m, q, r
if seed < 0:
raise ValueError("seed must be >=0")
self._z = seed + 1
def next_int(self):
k = self._z // self._q
self._z = self._a * (self._z - k * self._q) - self._r * k
if self._z < 0:
self._z += self._m
return self._z
[docs]class LCG0(LCG):
"""
First variant of LCG.
* a = 16807
* m = 2147483647
* q = 127773
* r = 2836
"""
[docs] def __init__(self, seed):
"""
:param seed: random seed to use
:type seed: int >= 0
"""
super().__init__(16807, 2147483647, 127773, 2836, seed)
[docs]class LCG1(LCG):
"""
Second variant of LCG.
* a = 48271
* m = 2147483647
* q = 44488
* r = 3399
"""
[docs] def __init__(self, seed):
"""
:param seed: random seed to use
:type seed: int >= 0
"""
super().__init__(48271, 2147483647, 44488, 3399, seed)
[docs]class LCG2(LCG):
"""
Third variant of LCG.
* a = 69621
* m = 2147483647
* q = 30845
* r = 23902
"""
[docs] def __init__(self, seed):
"""
:param seed: random seed to use
:type seed: int >= 0
"""
super().__init__(69621, 2147483647, 30845, 23902, seed)