Как получить согласованное поведение от C

#c #random

#c #Случайный

Вопрос:

Я столкнулся с проблемой, когда, если я повторно загружаю генератор случайных чисел из библиотеки 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:

Вы забыли сбросить состояние дистрибутива. Вызовите 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;
}
  

Живой пример с выводом