我想通过使用不同的种子数重置随机序列。运行此测试代码时:
boost::mt19937 gener(1);
boost::normal_distribution<> normal(0,1);
boost::variate_generator<boost::mt19937&,boost::normal_distribution<> > rng(gener, normal);
cout << rng() << endl;
cout << rng() << endl;
cout << rng() << endl;
gener.seed(2);
cout << rng() << endl;
cout << rng() << endl;
gener.seed(1);
cout << rng() << endl;
gener.seed(2);
cout << rng() << endl;
gener.seed(3);
cout << rng() << endl;
我得到以下输出:
# seed(1) via constructor
-2.971829031
1.706951063
-0.430498971
# seed(2)
-2.282022417
-0.5887503675
# seed(1)
0.2504171986
# seed(2)
-0.5887503675
# seed(3)
0.2504171986
显然我做错了。我怎么能克服这个问题?
答案 0 :(得分:14)
跟随Jim,Alan和Igor的建议对代码进行了一些更改:rng.engine().seed()
而不是gener.seed()
,并在调用rng.distribution().reset()
后调用rng.engine().seed()
魅力。
非常感谢!
答案 1 :(得分:5)
在调用gener.seed()之后,您应该调用normal.reset()。这是为了确保法线的输出不依赖于gener的任何先前输出。
(分发可能会缓存一些您需要清除的状态。)
答案 2 :(得分:1)
我相信boost::variate_generator<>
会复制您的boost::mt19937 gener
个对象。
因此,当您重新设定gener
的副本时,它对rng
对象已经没有影响
已建成。每次重新设置时构造一个新的rng
对象应该给你你想要的行为(免责声明:未经测试!)
答案 3 :(得分:1)
很高兴看到问题解决了!但我想我只是弄清楚为什么艾伦的方法不起作用......
撰写boost::variate_generator<boost::mt19937&,boost::normal_distribution<> > rng(gener, normal)
时,您没有创建gener
的另一个副本,因为它是通过引用进行的调用,但您已创建normal
的另一个副本使用variate_generate
。
因此,您应该使用normal.reset
而不是normal
,而只重置原始rng.distribution().reset()
。但你可以保留gener.seed()
,我怀疑它与rng.engine().seed()
具有相同的效果。
我在我的代码中测试了它,它按预期工作。
好吧,万一有人会关心:)