Python中的线性同余生成器
我正在用Python编写一个LCG函数,用于投币和生成运行的蒙特卡罗模拟。我面临的问题是,当我生成一个随机数列表时,这些数字的模式是赔率和偶数交替的。我不知道这是LCG函数本身的一个属性,还是我在生成数字时的一个错误 这是我的密码: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
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
,它将乘以一个奇数,对均匀度没有影响。