Python中的线性同余生成器

时间:2013-10-02 15:23:58

标签: python random

我正在用Python写一个LCG函数,我将用它来进行硬币翻转和生成运行的蒙特卡洛模型。我面临的问题是,当我生成一个随机数列表时,数字被图案化,使得赔率和均衡交替出现。我不知道这是LCG函数本身的属性还是我生成数字的错误。

这是我的代码:

def seedLCG(initVal):
    global rand
    rand = initVal

def lcg():
    a = 1140671485
    c = 128201163
    m = 2**24
    global rand
    rand = (a*rand + c) % m
    return rand

seedLCG(1)

for i in range(10):
    print lcg()

返回的值:

10581448
11595891
1502322
14136437
11348076
1403015
9622582
11013417
11529808
15836891

我假设我不需要担心溢出和大小因为int和long根据需要互换。

3 个答案:

答案 0 :(得分:4)

a*randrand乘以奇数,因此rand为奇数时结果始终为奇数,即使rand为偶数也是如此。然后添加奇数c,将奇数更改为偶数,反之亦然。模数对最后一位没有影响。因此,每次拨打lcg都会将rand从奇数转为偶数或从偶数转为奇数。

如果你对随机数字很认真(但你不需要加密数据),可以考虑使用numpy.random

答案 1 :(得分:2)

我相信你忘了在返回语句中用你的mod划分rand。它应该是这样的:

def lcg():
    a = 1140671485
    c = 128201163
    m = 2**24
    global rand
    rand = (a*rand + c) % m
    return rand / m

来源:http://people.duke.edu/~ccc14/sta-663-2016/15A_RandomNumbers.html

答案 2 :(得分:0)

晚会晚了一点,但对其他人来说可能很有趣。 在Python 3中,可以通过定义以下两个函数来构造伪随机数生成器:

def LCG(a, c, m, seed):     
    xi = seed
    while True:
        xf = (a * xi + c) % m
        xi = xf
        yield xf

def random_sample(n, interval, seed = 20200420162000):
    lower, upper = interval[0], interval[1]
    sample = []
    glibc = LCG(1103515245, 12345, 2 ** 32, seed)       # parameters as in GNU C Library

    for i in range(n):
        observation = (upper - lower) * (next(glibc) / 2 ** 32) + lower
        sample.append(int(observation))

    return sample

第一个函数是实现为生成器的实际LCG(即返回可迭代对象的函数),而第二个函数在生成器对象上迭代以获得样本。后者通常会被最终用户调用以在给定的时间间隔内生成随机数。

定义两个函数后,可以按以下方式使用它们:

sample = random_sample(100, [30, 90])   # 100 random numbers between 30 and 90
print(sample)

输出:

[54, 77, 41, 61, 74, 49, 65, 66, 86, 39, 53, 69, 88, 75, 56, 67, 73, 63, 81, 56, 81, 42, 43, 56, 35, 58, 72, 61, 84, 88, 49, 77, 85, 58, 87, 61, 48, 41, 41, 70, 49, 64, 73, 47, 51, 56, 32, 66, 55, 61, 79, 72, 83, 60, 83, 74, 84, 59, 82, 56, 71, 47, 34, 53, 72, 82, 75, 34, 70, 33, 46, 66, 55, 45, 64, 40, 46, 71, 82, 35, 77, 66, 87, 88, 58, 45, 80, 30, 37, 69, 31, 68, 89, 68, 85, 58, 65, 54, 57, 51]