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%