在失去随机性之前,std :: uniform_real_distribution会产生多少个随机数?

时间:2015-05-28 19:21:40

标签: c++ random

我正在为蒙特卡罗模拟编写c ++代码。因此,我需要生成在[0,1]之间均匀分布的许多数字。我在here中添加了以下代码来生成我的数字:

// uniform_real_distribution
#include <iostream>
#include <random>

std::default_random_engine generator;
std::uniform_real_distribution<double> distribution(0.0,1.0);

int main()
{  
    double number = distribution(generator); //rnd number uniformly distributed between [0,1)
    return 0;
}

因此,每当我需要新号码时,我只需拨打distribution(generator)。 我运行蒙特卡罗模拟以获得许多样本结果。结果应该正常分布在真实均值周围(未知)。当我运行卡方拟合优度检验以检查它们是否正常分布时,我的样本结果有时无法通过测试。这里的关键词是“有时”,所以这让我觉得我打了distribution(generator)太多次了,最后我失去了生成数字的随机性。我在谈论每次模拟中生成的10 ^ 11个数字。

有可能吗?如果我在调用之前使用distribution.reset()重置分发怎么办?这会解决我的问题吗?

感谢您提出任何建议。

3 个答案:

答案 0 :(得分:6)

如果随机数生成器有时没有通过测试,则测试太弱。例如,如果测试具有99%的置信度,那么一个完美的随机数生成器应该在大约1%的时间内失败。

例如,考虑一个完全公平的硬币。如果你翻转1000次,平均可以获得500个头。如果您想将此作为随机性的测试,您可以计算公平硬币在某个百分比内落入的值的范围。然后确保您的随机数生成器不会比预期更频繁地使测试失败。

您的测试方法 - 期望随机数生成器每次都通过每个测试 - 只有在您的测试非常弱的情况下才有效。这将使不良随机数生成器过于频繁地通过,并且不是一种好的测试方法。

真实故事:我实施的随机数生成器经an independent testing lab严格测试。他们进行了100次测试,每次测试使用数百万个样品并测试各种性能。每项测试的置信度均为99%。 RNG未通过3次测试,这是在预期的范围内,因此通过了认证的测试部分。 RNG通过了这些非常严格的测试,绝大部分时间都表明它是一个非常非常好的RNG,也许是完美的。编写一个通过任何这些测试的破损RNG很难。

您需要计算完美RNG未通过测试的概率,然后查看您的RNG是否显示接近预期的失败率。

答案 1 :(得分:1)

STL使用的随机生成器算法未在标准中指定,因此您无法确定随机序列的长度,而不知道使用了什么随机数生成算法。

它可能是一小部分已知的良好和快速的发电机,如梅森捻线机或CMWC。

有很多方法可以对随机数生成器进行评级,但在您的问题中,我认为您想知道这段时间 - 数字重复的时间。期限还取决于初始条件。

一个好的标准CMWC发生器,CMWC 4096的周期为2 ^ 131104。标准Mersenne发电机MT19937的周期为2 ^ 19937。

但是如果你使用的STL实现使用了一个选择不当的算法,那么所有的赌注都会被取消。

在每次通话之前重新播种,甚至经常重播,特别是如果没有很好地选择种子,将破坏发电机的统计特性。你通常最好只播种一次,并从那里调用它。

答案 2 :(得分:-1)

请注意,随机序列的强度取决于生成器,而不取决于分布。

关于default_random_engine the reference说&#34; 一个生成器,它为相对随意,不熟练和/或轻量级的使用提供至少可接受的引擎行为&#34 ; ...可能不是你想要的。

根据建议,您可以将其替换为std::mt19937,我不是专家,因此我不知道您可以在失去随机性之前使用它多长时间。

要更新生成器的随机性,您可以使用std::random_device并不时将其用于seed()生成器。在某些实现(您必须检查)上,random_device甚至使用CPU的特殊指令来生成&#34; hard&#34;随机数作为种子。唉,每次都不能简单地重新设置,因为这样的硬件生成速度很慢。