How to get consistent behavior from C++ <random>

大城市里の小女人 提交于 2020-01-04 02:20:37

问题


I'm running into an issue where if I reseed a random number generator from the C++ <random> library, I sometimes get an upcoming value from the sequence as the first sample. After that first sample, I get a repeatable sequence. There seems to be a pattern to it, but I can't quite work out what it is.

Minimal example:

#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;
}

Compiled using g++ (Ubuntu 7.3.0-27ubuntu1~18.04) without any flags on WSL Ubuntu 18.04.2.

I get the following output:

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

I would expect 0.3064 to always be the first value I get. I could work around this by burning off a sample after reseeding, but I don't see a clear pattern as to when I need to do that. Does anyone know why I'm getting the behavior? Is there a compiler flag I should be using?


回答1:


You forgot to reset the state of the distribution. Call nd.reset(); after seeding the engine.

Original code reproduced here with the fix:

#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



来源:https://stackoverflow.com/questions/55777705/how-to-get-consistent-behavior-from-c-random

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!