如何重置随机数引擎

How to reset a random number engine?

本文关键字:引擎 随机数 何重置      更新时间:2023-10-16

我正在尝试使用 C++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>

只是一个数学意义上的函数(确定性地从 x 中产生 y)还是我错过了什么?如果它只是一个函数,重置方法实际上做了什么?

您正在绑定引擎和发行版,例如以下重置调用不会影响绑定函数。

解决方案是将引用绑定到引擎和发行版

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

您遇到的问题是std::bind . std::bind复制其论点。std::bind制作副本的原因是,当参数可能不再存在时,该函数将在将来的某个未知时间点被调用。这意味着您对engine.seed()等的调用是无用的。使用 std::ref您可以通过引用绑定参数,这将为您提供预期的输出。

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