5

我正在用 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 的需要互换。

4

3 回答 3

6

a*rand乘以rand奇数,所以奇数时结果总是奇数rand,偶数时结果rand是偶数。然后添加奇数c,奇数变为偶数,反之亦然。模数对最后一位没有影响。因此,每次调用都会lcgrand奇数变为偶数或从偶数变为奇数。

如果您对随机数很认真(但您不需要加密强度的随机数),请考虑使用numpy.random.

于 2013-10-02T15:27:12.567 回答
4

聚会有点晚了,但对其他人来说可能很有趣。在 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(即返回可迭代对象的函数),而第二个函数遍历生成器对象以获取样本。后一个函数通常由最终用户调用以在给定间隔内生成伪随机数。

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

# 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]
于 2019-11-14T22:19:08.900 回答
3

我相信您忘记rand在 return 声明中除以您的 mod。它应该如下所示:

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

于 2017-06-26T00:43:54.280 回答