std :: mt19937不返回随机数

时间:2015-04-09 22:04:44

标签: c++ random prng

我有以下代码:

unsigned int randomInt()
{
    mt19937 mt_rand(time(0));
    return mt_rand();
};

如果我在for循环中调用此代码,例如4000次,我不会得到随机无符号整数,而是获得1000次一个值,接下来1000次获得下一个值。

我做错了什么?

2 个答案:

答案 0 :(得分:8)

这是因为你在一个循环中调用f 4000次,这可能需要不到一秒的时间,因此在每次调用时time(0)返回相同的值,因此初始化伪随机生成器同一个种子。正确的方法是一劳永逸地初始化种子,最好是通过std::random_device,如下所示:

#include <random>
#include <iostream>

static std::random_device rd; // random device engine, usually based on /dev/random on UNIX-like systems
// initialize Mersennes' twister using rd to generate the seed
static std::mt19937 rng(rd()); 

int dice()
{
    static std::uniform_int_distribution<int> uid(1,6); // random dice
    return uid(rng); // use rng as a generator
}

int main()
{
    for(int i = 0; i < 10; ++i)
        std::cout << dice() << " ";   
}

答案 1 :(得分:0)

随机源是属于整个程序的资源,而不属于单一功能。您应该永远在用于返回随机值的例程中创建随机源。

好的选择包括:

  • 将随机源传递给您的函数
  • 使您的随机源成为全局变量
  • 使您的随机源成为静态变量,以便初始化发生一次。

您可能认为尝试不应该做的一件事就是用具有更高分辨率的类似函数替换time(0);虽然你会得到不同的结果,但这仍会产生质量差的随机数,甚至可能比正确生成随机数慢得多。 (我相信有一些随机数生成器可以正常使用这些用法,但那些必须是为此目的而设计的)