我遇到了一个问题,如果我从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/

10-09 03:38