【问题标题】:How to reset a random number engine?如何重置随机数引擎?
【发布时间】:2012-06-15 00:53:24
【问题描述】:

我正在尝试使用 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)还是我遗漏了什么?如果只是一个函数,那么reset方法实际上是做什么的呢?

【问题讨论】:

    标签: c++ random c++11


    【解决方案1】:

    您正在绑定引擎和分发,因此以下重置调用不会影响绑定的功能。

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

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

    【讨论】:

    • 就是这样。我想我必须更多地学习 STL :) 它与您的解决方案完美配合。谢谢!
    • auto generator = std::bind(normal, std::ref(engine)); 我猜就够了。
    【解决方案2】:

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

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

    【讨论】:

      猜你喜欢
      • 2013-05-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-11-07
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多