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