Как посеять генератор случайных чисел?
Я смотрел на пример генерации случайных чисел с нормальным распределением на cppreference.com и немного изменил код, чтобы получить это:
#include <iostream>
#include <random>
struct MyNormalDistribution {
static double getRandomNumber(double mean,double std_dev){
return std::normal_distribution<>(mean,std_dev)(MyNormalDistribution::generator);
}
private:
static std::random_device rand;
static std::mt19937 generator;
};
std::random_device MyNormalDistribution::rand;
std::mt19937 MyNormalDistribution::generator = std::mt19937(MyNormalDistribution::rand());
int main(int argc, char *argv[]) {
for (int t=0;t<10;t++){
std::cout << MyNormalDistribution::getRandomNumber(0,10) << std::endl;
}
}
Однако всякий раз, когда я запускаю это, я получаю одну и ту же последовательность чисел. Есть ли какая-то глупая ошибка, или пример cppreference не содержит правильного заполнения?
Как правильно посеять семена MyNormalDistribution
?
2 ответа
Например, можно запустить генератор с текущим временем:
#include <iostream>
#include <random>
struct MyGenerator {
std::mt19937 gen;
static std::random_device rand;
MyGenerator() : generator(rand()){ gen.seed(time(0)); }
};
std::random_device MyGenerator::rand;
struct MyNormalDistribution {
static double getRandomNumber(double mean,double std_dev){
return std::normal_distribution<>(mean,std_dev)(MyNormalDistribution::gen.gen);
}
private:
static MyGenerator gen;
};
MyGenerator MyNormalDistribution::gen;
Как написано в cppreference.com, "проблема" находится в вашем std:: random_device:
std:: random_device может быть реализован в терминах механизма псевдослучайных чисел, определенного в реализации, если недетерминированный источник (например, аппаратное устройство) не доступен для реализации. В этом случае каждый объект std:: random_device может генерировать одинаковую числовую последовательность.
Другими словами, я думаю, что вы используете ОС Linux, и у вас не установлена опция 'CONFIG_HW_RANDOM' в вашем ядре. В качестве альтернативы вы можете просто использовать другой источник начального значения, такой как системные часы.
auto seed = std::chrono::system_clock::now().time_since_epoch().count();
std::mt19937 generator {seed};