我遇到了一个问题,如果我从C++ <random>
库重新设置了一个随机数生成器,有时我会从序列中获得即将出现的值作为第一个示例。在第一个样本之后,我得到了一个可重复的序列。似乎有一种模式,但我不能完全弄清楚它是什么。
最小示例:
#include <iostream>
#include <random>
using namespace std;
int main(){
mt19937 engine {1};
normal_distribution<float> nd {0, 1};
for (int i=0; i<10; i++){
for (int j=0; j<=i; j++) {
cout << nd(engine) << endl;
}
cout << endl;
engine.seed(1);
}
return 0;
}
在WSL Ubuntu 18.04.2。上使用g++(Ubuntu 7.3.0-27ubuntu1〜18.04)进行编译且没有任何标志。
我得到以下输出:
0.3064
0.156066
0.3064
0.156066
0.3064
0.156066
0.3064
0.156066
-0.424386
-0.56804
0.3064
0.156066
-0.424386
-0.56804
-0.204547
-0.806289
0.3064
0.156066
-0.424386
-0.56804
-0.204547
-0.806289
0.3064
0.156066
-0.424386
-0.56804
-0.204547
-0.806289
0.3064
0.156066
-0.424386
-0.56804
-0.204547
-0.806289
-0.428738
-1.20004
0.3064
0.156066
-0.424386
-0.56804
-0.204547
-0.806289
-0.428738
-1.20004
1.30547
-1.18775
0.3064
0.156066
-0.424386
-0.56804
-0.204547
-0.806289
-0.428738
-1.20004
1.30547
我希望0.3064永远是我得到的第一个值。我可以通过在重新播种后烧掉一个样本来解决此问题,但是我看不到何时需要这样做的明确模式。有人知道我为什么要这样吗?我应该使用编译器标志吗?
最佳答案
您忘记了重置发行版的状态。播种引擎后,调用nd.reset();
。
原始代码在此复制并修复:
#include <iostream>
#include <random>
using namespace std;
int main(){
mt19937 engine {1};
normal_distribution<float> nd {0, 1};
for (int i=0; i<10; i++){
for (int j=0; j<=i; j++) {
cout << nd(engine) << endl;
}
cout << endl;
engine.seed(1);
nd.reset();
}
return 0;
}
Live example with output
关于c++ - 如何从C++ <random>中获得一致的行为,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/55777705/