我似乎看到很多答案,有人建议使用它<random>来生成随机数,通常伴随着这样的代码:
std::random_device rd;
std::mt19937 gen(rd());
std::uniform_int_distribution<> dis(0, 5);
dis(gen);
Run Code Online (Sandbox Code Playgroud)
通常这会取代某种"邪恶的憎恶",例如:
srand(time(NULL));
rand()%6;
Run Code Online (Sandbox Code Playgroud)
我们可能会批评旧的方式,认为time(NULL)提供低熵,time(NULL)可预测,最终结果是不均匀的.
但所有这一切都适用于新的方式:它只有一个更光亮的贴面.
rd()返回一个unsigned int.这至少有16位,可能是32位.这还不足以为MT的19937位状态提供种子.
使用std::mt19937 gen(rd());gen()(以32位播种并查看第一个输出)不能提供良好的输出分布.7和13永远不会是第一个输出.两粒种子产生0.十二粒种子产生1226181350.(链接)
std::random_device可以(有时是)实现为具有固定种子的简单PRNG.因此,它可能在每次运行时产生相同的序列.(链接)这甚至比time(NULL).
更糟糕的是,尽管存在它们包含的问题,但复制和粘贴上述代码片段非常容易.对此的一些解决方案需要获得可能不适合每个人的大型 库.
鉴于此,我的问题是如何在C++中简洁,便携,彻底地播种mt19937 PRNG?
鉴于上述问题,一个很好的答案:
std::random_device或time(NULL)作为熵的来源.思考
我使用以下代码来测试c++ <random>库.
为什么每次运行已编译的可执行文件时都会得到完全相同的序列?rd()编译是确定性的吗?如何为每次运行获得不同的输出?
Windows 7 64位上的GCC 4.8.1.使用http://nuwen.net/mingw.html上的 MinGW发行版
编辑:我用Visual Studio测试了相同的代码.没有问题.输出是不确定的.这可能是我使用的mingw gcc 4.8.1中的一个错误.
#include <iostream>
#include <random>
using namespace std;
int main(){
random_device rd;
mt19937 mt(rd());
uniform_int_distribution<int> dist(0,99);
for (int i = 0; i< 16; ++i){
cout<<dist(mt)<<" ";
}
cout <<endl;
}
Run Code Online (Sandbox Code Playgroud)