如何从C ++ <random>

时间:2019-04-20 21:02:56

标签: c++ random

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

使用g ++(Ubuntu 7.3.0-27ubuntu1〜18.04)编译,在WSL Ubuntu 18.04.2。上没有任何标志。

我得到以下输出:

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始终是我得到的第一个值。我可以通过在重新播种后烧掉一个样本来解决此问题,但是我看不到何时需要这样做的明确模式。有谁知道我为什么要这样?我应该使用编译器标志吗?

1 个答案:

答案 0 :(得分:8)

您忘记了重置发行版的状态。播种引擎后,调用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