Как посеять генератор случайных чисел?

Я смотрел на пример генерации случайных чисел с нормальным распределением на 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};
Другие вопросы по тегам