如何测试随机数生成器是否生成实际随机数?
我的方法:首先构建一个大小为M的哈希值,其中M是素数。然后取数字 由随机数生成器生成,并使用M. 并看到它填写所有哈希或只是在某些部分。 这是我的方法。我们可以用可视化证明它吗?
因为我对测试知之甚少。你能建议我彻底解决这个问题吗?提前致谢
答案 0 :(得分:11)
您应该知道,保证随机数生成器工作正常。请注意,即使是在[1,10]范围内的完美均匀分布 - 在10个数字的随机抽样中,有10个 -10 的机会得到10倍10。
可能吗?当然不是。
那么 - 可以我们做什么?
如果随机数生成器确实是均匀分布的,我们可以统计证明组合(10,10,....,10)不太可能。这个概念叫做 Hypothesis testing 。通过这种方法,我们可以说“确定性水平为x% - 我们可以拒绝数据取自均匀分布的假设”。
常用的方法是使用 Pearson's Chi-Squared test ,这个想法与你的相似 - 你填写一张表 - 检查观察到的是什么 (生成)每个单元格的数字,以及零假设下每个单元格的预期数字是多少(在您的情况下,预期为k/M
- 其中M是范围的大小,k是所采用的数字的总数)。
然后,您对数据进行一些操作(有关此操作的详细信息,请参阅维基百科文章) - 并获取一个数字(测试统计信息)。然后,检查此号码是否可能从Chi-Square Distribution中获取。如果是 - 你不能拒绝零假设,如果不是 - 你可以肯定x%确定数据不是从统一随机生成器中获取的。
编辑:示例:
你有一个立方体,你想检查它是否“公平”(在[1,6]
中统一分布)。抛出200次(例如)并创建下表:
number: 1 2 3 4 5 6
empirical occurances: 37 41 30 27 32 33
expected occurances: 33.3 33.3 33.3 33.3 33.3 33.3
现在,根据Pearson的测试,统计数据是:
X = ((37-33.3)^2)/33.3 + ((41-33.3)^2)/33.3 + ... + ((33-33.3)^2)/33.3
X = (18.49 + 59.29 + 10.89 + 39.69 + 1.69 + 0.09) / 33.3
X = 3.9
对于随机C~ChiSquare(5)
,高于3.9
的概率为~0.45
(这是不可能的) 1 。
所以我们不能拒绝原假设,我们可以得出结论,数据可能均匀分布在[1,6]
(1)如果该值小于0.05,我们通常会拒绝零假设,但这非常依赖于案例。
答案 1 :(得分:1)
我天真的想法:
发电机正在进行分配。 (至少它应该。)执行合理数量的运行,然后在图表上绘制值。在点上拟合回归曲线。如果它与分布的形状相关,那么你就是好的。 (这也可以在1D中使用投影和直方图。并且可以使用正确的工具完全自动化,例如MatLab)
你也可以像之前提到的那样使用死硬测试,这肯定会更好,但更少直觉,至少在你身边。
答案 2 :(得分:0)
假设您想在区间[0,1]上生成均匀分布。
然后一个可能的测试是
for i from 1 to sample-size
when a < random-being-tested() < b
counter +1
return counter/sample-size
看看结果是否接近b-a(b减去a)。
当然你应该定义一个函数,将a,b在0和1之间作为输入,并返回counter / sample-size和b-a之间的差值。循环通过可能的a,b,比如0.01的倍数,a&lt;湾当差值大于预设的epsilon时,打印出a,b,比如说0.001。
那些是异常值太多的a,b。
如果您让样本量为5000.您的随机测试将被称为总共5000 * 5050次,希望不会太糟糕。
答案 3 :(得分:0)
我遇到了同样的问题。 当我完成编写代码时(使用外部RNG引擎)
我查看了结果,发现每当我得到很多结果时,所有这些都无法通过卡方检验。
我的代码生成了一个随机数并保存了每个结果范围的数量。 我不知道为什么当我有很多结果时,卡方检验失败了。
在我的研究中,我发现C#Random.next()在任何随机范围内失败,并且有些数字的赔率高于另一个,更多的我看到RNGCryptoServiceProvider随机提供商不支持号。
当试图获得0-1,000,000,000范围内的数字时,0-300M范围内的数字出现的概率更高......
因此我正在使用RNGCryptoServiceProvider,如果我的范围高于100M,我将我自己的数字(RandomHigh * 100M + RandomLow)和两个randoms的范围小于100M,这样就很好了。< / p>
祝你好运!