是蟒蛇random.randint统计学随机的?(Is Pythons random.randint

2019-06-27 11:28发布

所以,我测试的计算一定掷骰的概率,对于一个游戏。 基底情况下,如果使滚动一个10sided裸片。

我做的这一个亿个样本,并结束了与以下比例:

Result
0       0.000000000000000%
1       10.038789961210000%
2       10.043589956410000%
3       9.994890005110000%
4       10.025289974710000%
5       9.948090051909950%
6       9.965590034409970%
7       9.990190009809990%
8       9.985490014509990%
9       9.980390019609980%
10      10.027589972410000%

这些当然应该都是10%。 还有就是0.0323207%,在这些结果的标准偏差。 这对我来说,是相当高的。 难道仅仅是巧合吗? 据我所知随机模块访问适当的伪随机数。 从一个方法,即那些通过统计检验是随机的。 或者是这些伪伪随机数生成器

我应该使用的加密伪随机数发生器? 我相当肯定,我并不需要一个真正的随机数发生器(见http://www.random.org/ , http://en.wikipedia.org/wiki/Hardware_random_number_generator )。

我目前再生我的所有结果以1个十亿样品,(COS为什么不呢,我有我的处置脆脆的服务器,以及一些睡眠办)

Answer 1:

马亭的回答是,Python有访问随机数生成器的一个非常简洁的审查。

如果你想看看生成的伪随机数据的属性,下载random.zip从http://www.fourmilab.ch/random/ ,并在随机数据的大样本运行它。 尤其是χ²(卡方)检验是随机性非常敏感。 对于一个序列是真正随机的,从χ²测试的比例应为10%和90%之间。

对于比赛我猜Mersenne扭曲了Python内部使用应该是足够随机的(除非你:-)建立一个网上赌场。

如果你想单纯的随机性,如果你使用的是Linux,你可以从阅读/dev/random 。 这仅产生从内核的熵池随机数据(这是从中断到达的不可预测的时间聚集),所以如果你用尽它,它会阻止。 这个熵用于初始化(种子)由所使用的PRNG /dev/urandom 。 在FreeBSD,所述PRNG供给数据/dev/random使用亚罗算法,这一般认为是加密安全。

编辑:我跑从字节一些测试random.randint 。 首先创造100万个随机字节:

import random
ba = bytearray([random.randint(0,255) for n in xrange(1000000)])
with open('randint.dat', 'w+') as f:
    f.write(ba)

然后我跑了ent从程序Fourmilab就可以了:

Entropy = 7.999840 bits per byte.

Optimum compression would reduce the size
of this 1000000 byte file by 0 percent.

Chi square distribution for 1000000 samples is 221.87, and randomly
would exceed this value 93.40 percent of the times.

Arithmetic mean value of data bytes is 127.5136 (127.5 = random).
Monte Carlo value for Pi is 3.139644559 (error 0.06 percent).
Serial correlation coefficient is -0.000931 (totally uncorrelated = 0.0).

现在的χ²测试中,进一步从50%得到的,就越怀疑的数据。 如果一个是非常挑剔,值<10%或> 90%的被认为是不可接受的。 约翰·沃克的作者, ent调用此值“几乎是犯罪嫌疑人”。

作为对比,这里是从FreeBSD的亚罗PRNG我在前面跑10个MIB同样的分析:

Entropy = 7.999982 bits per byte.

Optimum compression would reduce the size
of this 10485760 byte file by 0 percent.

Chi square distribution for 10485760 samples is 259.03, and randomly
would exceed this value 41.80 percent of the times.

Arithmetic mean value of data bytes is 127.5116 (127.5 = random).
Monte Carlo value for Pi is 3.139877754 (error 0.05 percent).
Serial correlation coefficient is -0.000296 (totally uncorrelated = 0.0).

虽然似乎有在其他数据没有太大的区别,χ²PRECENTAGE 接近50%。



Answer 2:

random模块文档 :

几乎所有的模块功能取决于基本函数random(),它在半开区间[0.0,1.0)中均匀地产生一个随机浮点数。 Python使用梅森难题为核心的发电机。 它产生53位精度浮点值,并且具有一周期的2 ** 19937-1。 在C中的底层实现快速和线程。 梅森倍捻机是现存的最广泛的测试,随机数生成器之一。 然而,在完全确定的,它不适合所有的目的,是完全不适合加密的目的。

从上梅森倍捻机维基百科的文章 :

它提供了快速生成非常高品质的伪随机数,其经过专门设计,解决了许多中老年算法中发现的缺陷。

如果你有一个特定的OS随机性源,可通过os.urandom()那么你可以使用random.SystemRandom()类代替。 大多数的random模块功能都可以在这个类的方法。 这也许会更适合加密的目的,再次引用文档:

返回的数据应该是足够的加密应用程序不可预测的,但其确切的质量取决于操作系统的实现。

蟒3.6增加了一个secrets模块用方便的方法来产生随机数据适于密码用途:

secrets模块用于生成适合于管理如密码数据加密的强随机号码,帐户认证,安全令牌,以及相关的秘密。

在特别地, secrets应优先使用缺省的伪随机数发生器中random模块,其被设计用于建模和仿真,而不是安全或加密。



Answer 3:

我重新进行了OP的锻炼一个十亿次迭代:

from collections import Counter
import random
n = 1000000000
c = Counter(random.randint(1, 10) for _ in xrange(n))
for i in range(1,11):
    print '%2s  %02.10f%%' % (i, c[i] * 100.0 / n)

这里是(格式化)结果:

 1     9.9996500000%
 2    10.0011089000%
 3    10.0008568000%
 4    10.0007495000%
 5     9.9999089000%
 6     9.9985344000%
 7     9.9994913000%
 8     9.9997877000%
 9    10.0010818000%
10     9.9988307000%

见对方回答这个问题的杰出分析。



Answer 4:

是的,这是所有的实际目的统计学随机的。 您看到的随机变化是完全正常的。 事实上,它是一个贫穷的RNG,如果没有这样的变化。

由于PRNG的周期为2 ** 19937-1,你需要比有宇宙中的原子你看到一个非随机分配之前产生更多的数字。 请注意,如果您生成623个维向量,就变成非随机更快。



Answer 5:

这的确是正常的随机数,拿出一个很好的PRNG不完全分布。 但是,你产生更多的数字,越少,你应该看到这一点。

顺便说一句,我得到的0.03066的标准偏差,这是比你给的略低。



Answer 6:

这些结果是非常接近你期望什么,并有一个简单的计算,你可以做检查。 如果你滚百万D10S和计数1秒的数量(说)是随机变量的均值为10万(试行次数*成功的概率)和方差90000(试行次数*成功的概率*故障的概率),这样的标准偏差是SQRT(90,000)= 300。 所以,你应该期望得到的东西约300 100,000远,即10%+/- 0.03%。



文章来源: Is Pythons random.randint statistically random?