Python中的线性同余生成器

Python中的线性同余生成器,python,random,Python,Random,我正在用Python编写一个LCG函数,用于投币和生成运行的蒙特卡罗模拟。我面临的问题是,当我生成一个随机数列表时,这些数字的模式是赔率和偶数交替的。我不知道这是LCG函数本身的一个属性,还是我在生成数字时的一个错误 这是我的密码: def seedLCG(initVal): global rand rand = initVal def lcg(): a = 1140671485 c = 128201163 m = 2**24 global ra

我正在用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可以根据Python的需要进行交换。

a*rand
rand
乘以一个奇数,因此当
rand
为奇数时,结果总是奇数;当
rand
为偶数时,结果总是偶数。然后添加奇数
c
,奇数变为偶数,奇数变为偶数。模对最后一位没有影响。因此,每次对
lcg
的调用都会将
rand
从奇数翻转到偶数或从偶数翻转到奇数


如果你对随机数很认真(但是你不需要密码强度的),考虑使用.< /P> < P>我相信你忘记了你的MOD在返回语句中划分代码> RAND 。应该是这样的:

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

资料来源:

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

def lcg(x, a, c, m):
    while True:
        x = (a * x + c) % m
        yield x


def random_uniform_sample(n, interval, seed=0):
    a, c, m = 1103515245, 12345, 2 ** 31
    bsdrand = lcg(seed, a, c, m)

    lower, upper = interval[0], interval[1]
    sample = []

    for i in range(n):
        observation = (upper - lower) * (next(bsdrand) / (2 ** 31 - 1)) + lower
        sample.append(round(observation))

    return sample
第一个函数是作为生成器实现的实际LCG(即返回iterable对象的函数),而第二个函数迭代生成器对象以获取样本。后一个函数通常由最终用户调用,以在给定间隔内生成伪随机数

在定义了这两个功能之后,可以按如下方式使用它们:

# 30 numbers between 0 and 100
rus = random_uniform_sample(30, [0, 100])
print(rus)
输出:

[0, 66, 30, 67, 11, 52, 49, 60, 37, 26, 37, 83, 17, 30, 64, 79, 99, 80, 46, 54, 63, 25, 70, 72, 98, 33, 45, 71, 74, 17]

为什么要实现自己的,而不是使用python的内置生成器或numpy的选项呢?我只是想了解LCG是如何工作的。我对内置的发电机也做了同样的模拟。答案合理。现在您知道了LCG工作原理的答案是“糟糕”。为什么不使用:random.seed(initval)并获得一个新值:random.randint(0,2**24)?好的,这是有道理的。我有几个后续问题。为什么模对最后一位没有影响?这是所有LCG生成器的一个属性,还是将参数“a”更改为“a*rand”始终具有偶数值会产生影响?@SiddharthDhingra:因为模2^k不会影响低阶k位。至于
a*rand
,它将乘以一个奇数,对均匀度没有影响。