随机数发生器测试

时间:2012-08-30 04:51:06

标签: algorithm unit-testing testing

如何测试随机数生成器是否生成实际随机数?

我的方法:首先构建一个大小为M的哈希值,其中M是素数。然后取数字              由随机数生成器生成,并使用M.              并看到它填写所有哈希或只是在某些部分。              这是我的方法。我们可以用可视化证明它吗?

因为我对测试知之甚少。你能建议我彻底解决这个问题吗?提前致谢

4 个答案:

答案 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>

祝你好运!