Python 蟒蛇是随机的吗?

Python 蟒蛇是随机的吗?,python,random,statistics,probability,Python,Random,Statistics,Probability,所以我在测试一个计算某个掷骰子的概率的游戏。 基本情况下,如果滚动单面模具 我做了一百万个样本,最后得出以下比例: Result 0 0.000000000000000% 1 10.038789961210000% 2 10.043589956410000% 3 9.994890005110000% 4 10.025289974710000% 5 9.948090051909950% 6 9.9655900344

所以我在测试一个计算某个掷骰子的概率的游戏。 基本情况下,如果滚动单面模具

我做了一百万个样本,最后得出以下比例:

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%。 在我看来,这似乎相当高。 这只是巧合吗? 据我所知,随机模块访问正确的伪随机数。 也就是说,通过统计测试的方法得出的结果是随机的。 还是这些伪随机数生成器

我应该使用加密伪随机数生成器吗? 我相当确定我不需要真正的随机数生成器(请参阅)

我目前正在用10亿个样本重新生成所有结果, (因为为什么不呢,我有一个松脆的服务器在我的支配下,还有一些睡眠要做)

来自:

几乎所有模块函数都依赖于基本函数random(),该函数在半开放范围内均匀生成随机浮点[0.0,1.0)。Python使用Mersenne Twister作为核心生成器。它产生53位精度浮点,周期为2**19937-1。C中的底层实现既快速又线程安全。Mersenne Twister是现有测试最广泛的随机数生成器之一。但是,由于完全确定性,它不是适用于所有目的,并且完全不适用于加密目的

从:

它提供了快速生成高质量伪随机数的功能,专门用于纠正旧算法中发现的许多缺陷

如果您有一个特定于操作系统的随机性源,可通过使用,那么您可以使用该类。大多数
随机
模块函数可作为该类上的方法使用。它可能更适合用于加密目的,再次引用文档:

对于加密应用程序来说,返回的数据应该是不可预测的,尽管其确切质量取决于操作系统的实现

Python 3.6添加了一个方便的方法来生成适用于加密目的的随机数据:

secrets
模块用于生成适合管理密码、帐户身份验证、安全令牌和相关机密等数据的加密强随机数

特别是,应优先使用
机密
,而不是
随机
模块中的默认伪随机数生成器,它是为建模和仿真而设计的,而不是为了安全或加密


是的,从统计上看,它是随机的。你看到的随机变化是完全正常的。事实上,如果没有那样的变化,它将是一个很差的rng


因为prng的周期是2**19937-1,所以在看到非随机分布之前,你需要生成比宇宙中原子更多的数字。请注意,如果生成623维向量,它会很快变成非随机的。

Martijn的答案是对Python的随机数生成器的一个非常简洁的回顾访问

如果要检查生成的伪随机数据的属性,请从下载
random.zip
,并在大样本随机数据上运行它。特别是χ²(卡方)检验对随机性非常敏感。对于真正随机的序列,χ²检验的百分比应在10%到90%之间

对于一个游戏,我想Python内部使用的Mersenne Twister应该是足够随机的(除非您正在构建一个在线赌场:-)

如果您想要纯粹的随机性,并且使用Linux,您可以从
/dev/random
读取。这只会从内核的熵池(从中断到达的不可预测时间收集)生成随机数据,因此如果耗尽它,它将阻塞。此熵用于初始化(种子)
/dev/urandom
使用的PRNG。在FreeBSD上,为
/dev/random
提供数据的PRNG使用Yarrow算法,这通常被认为是加密安全的

编辑:我对
random.randint
中的字节进行了一些测试。首先创建了一百万个随机字节:

import random
ba = bytearray([random.randint(0,255) for n in xrange(1000000)])
with open('randint.dat', 'w+') as f:
    f.write(ba)
然后我在上面运行了
ent
程序:

对于χ²检验,你从50%得到的数据越远,数据就越可疑。如果一个数据非常挑剔,那么90%的值被认为是不可接受的。约翰·沃克(John Walker)是
ent
的作者,他称这个值“几乎可疑”

作为对比,以下是我之前对FreeBSD的Yarrow 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).

虽然在其他数据中似乎没有太大差异,但χ2的比例更接近50%。

随机数出现不完全分布和良好PRNG确实是正常的。但是,生成的数字越多,你应该看到的越少


顺便说一句,我得到的标准偏差为0.03066,略低于您给出的值。

我用10亿次迭代重新运行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)
以下是(重新格式化)的结果:


查看这个问题的其他答案,了解他们的出色分析。

这些结果非常接近您的预期,您可以做一个简单的计算来验证这一点。如果您滚动1000000个D10并计算1的数量(例如),该随机变量的平均值为100000(试验次数*成功概率)方差是90000(试验次数*成功概率*失败概率),所以标准偏差是sqrt(90000)=300。所以你应该期望从100000中得到大约300,即10%+/-0.03%。

你能发布你的代码吗?我的代码基本上是:
random.randint(1,10)
他们的想法没什么大不了的,(还有一些其他的东西会产生效果。)
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%