我正在尝试使用C ++ 11方法生成随机数:
#include <random>
#include <functional>
#include <iostream>
int main(int argc, char *argv[])
{
std::normal_distribution<double> normal(0, 1);
std::mt19937 engine; // Mersenne twister MT19937
auto generator = std::bind(normal, engine);
int size = 2;
engine.seed(0);
normal.reset();
for (int i = 0; i < size; ++i)
std::cout << generator() << std::endl;
std::cout << std::endl;
engine.seed(1);
normal.reset();
for (int i = 0; i < size; ++i)
std::cout << generator() << std::endl;
std::cout << std::endl;
engine.seed(0);
normal.reset();
for (int i = 0; i < size; ++i)
std::cout << generator() << std::endl;
return 0;
}
输出结果为:
0.13453
-0.146382
0.46065
-1.87138
0.163712
-0.214253
这意味着第一个和第三个序列即使用相同的数字播种也不相同。拜托,我做错了什么?是
std::normal_distribution<double>
只是数学意义上的函数(确定性地从x中产生y)或者我错过了什么?如果它只是一个函数,重置方法实际上做了什么?
答案 0 :(得分:19)
您正在绑定引擎和分发,例如以下重置调用不会影响绑定功能。
解决方案是绑定对引擎和发行版的引用
auto generator = std::bind(std::ref(normal), std::ref(engine));
答案 1 :(得分:11)
您遇到的问题是std::bind
。 std::bind
复制其论点。 std::bind
复制的原因是因为当参数可能不再存在时,函数将在未来的某个未知点被调用。这意味着您对engine.seed()
等的来电无效。使用std::ref
,您可以通过引用绑定您的参数,这将为您提供预期的输出。
auto generator = std::bind(std::ref(normal), std::ref(engine));