Подтвердить что ты не робот

Как reset движок случайных чисел?

Я пытаюсь использовать подход С++ 11 для генерации случайных чисел:

#include <random>
#include <functional>
#include <iostream>

int main(int argc, char *argv[])
{    
    std::normal_distribution<double> normal(0, 1);
    std::mt19937 engine; // Mersenne twister MT19937
    auto generator = std::bind(normal, engine);

    int size = 2;

    engine.seed(0);
    normal.reset();
    for (int i = 0; i < size; ++i)
        std::cout << generator() << std::endl;

    std::cout << std::endl;

    engine.seed(1);
    normal.reset();
    for (int i = 0; i < size; ++i)
        std::cout << generator() << std::endl;

    std::cout << std::endl;

    engine.seed(0);
    normal.reset();
    for (int i = 0; i < size; ++i)
        std::cout << generator() << std::endl;

    return 0;
}

Вывод:

0.13453
-0.146382

0.46065
-1.87138

0.163712
-0.214253

Это означает, что первая и третья последовательности не идентичны, даже если они засеяны одним и тем же числом. Пожалуйста, что я делаю неправильно? Является

std::normal_distribution<double>

Просто функция в математическом смысле (выдает y из x детерминистически) или мне что-то не хватает? Если это просто функция, что делает метод reset?

4b9b3361

Ответ 1

Вы связываете движок и дистрибутив, поэтому следующие вызовы reset не влияют на связанную функцию.

Решением является привязка ссылок на движок и дистрибутив

auto generator = std::bind(std::ref(normal), std::ref(engine));

Ответ 2

У вас проблема с std::bind. std::bind делает копии своих аргументов. Причина std::bind делает копии, потому что функция будет вызываться в какой-то неизвестной точке в будущем, когда аргументы могут больше не существовать. Это означает, что ваши вызовы на engine.seed() и т.д. Бесполезны. Используя std::ref, вы можете привязать свои аргументы по ссылке, которая даст вам ожидаемый результат.

auto generator = std::bind(std::ref(normal), std::ref(engine));