【问题标题】:Encapsulated Random number generator in C++-11 using boost使用 boost 在 C++-11 中封装的随机数生成器
【发布时间】:2015-10-03 18:13:09
【问题描述】:

我正在尝试使用 boost 在 C++-11 中生成随机数。我看过一些关于这个的好帖子,我能够生成随机数,将我的所有代码放在主函数中,就像这个网页(http://www.sitmo.com/article/generating-random-numbers-in-c-with-boost/)中建议的那样。

但是,我无法封装可由不同函数调用的随机数生成器 (RNG)。我希望这个封装的 RNG 接收数字范围和随机种子作为参数。我尝试按照这篇文章 (Boost random number generator) 的建议来做。

我实现了下面的代码。但它在两个方面都失败了:随机种子的变化和值范围的定义。

#include <boost/random/variate_generator.hpp>
#include <boost/generator_iterator.hpp>
#include <boost/random/mersenne_twister.hpp>
#include <boost/random/normal_distribution.hpp>

typedef boost::mt19937                     ENG;    // Mersenne Twister
typedef boost::normal_distribution<double> DIST;   // Normal Distribution
typedef boost::variate_generator<ENG,DIST> GEN;    // Variate generator

class RNG {

  private:
     ENG eng;
     DIST dist;

  public:
     GEN gen;
     RNG(double min,double max,int seed)
     : dist(min,max), gen(eng,dist)
     {eng.seed(seed); }
};

这是我的主要功能。

int main(int argc, char **argv){
    if(argc == 2){
        int myseed = atoi(argv[1]);
        double minimum = 1.;
        double maximum = 10.;
        int N = 20;

        RNG myrn(minimum,maximum,myseed);

        for (int i = 0; i < N; i++){
            std::cout << myrn.gen() << std::endl;
        }
            return 0;
    }
    exit(1);
}

此实现独立于我使用的种子生成相同的随机数序列。此外,随机数不在最小值和最大值之间的范围内。有谁知道如何解决这两个问题?

【问题讨论】:

    标签: c++ c++11 boost random


    【解决方案1】:

    boost::variate_generator 按值获取其构造函数参数,因此当您在 mem-initializer 列表中传递一个默认构造的 mt19937 时,它会复制它。在构造函数的主体内播种引擎对该副本没有影响。要解决此问题,请将模板参数类型更改为引用。

    typedef boost::variate_generator<ENG&,DIST> GEN;
    //                                  ^
    

    接下来,我认为你不需要normal_distribution,它的构造函数参数不是分布产生的值范围的最小值和最大值,而是分布的均值和标准差。

    您可能正在寻找的发行版是uniform_real_distribution

    typedef boost::random::uniform_real_distribution<> DIST;
    

    进行这些修复后,您的代码应该按照您的意愿运行。

    Live demo


    使用 C++11 编译器,您甚至不需要 Boost 来执行此操作,&lt;random&gt; 标头提供了您需要的所有组件。唯一显着的区别是缺少variate_generator 类,而是在您想要生成随机数时使用引擎作为参数调用分发对象。

    #include <random>
    
    typedef std::mt19937                     ENG;    // Mersenne Twister
    typedef std::uniform_real_distribution<> DIST;   // Uniform Distribution
    
    class RNG {
    
      private:
         ENG eng;
         DIST dist;
    
      public:
         DIST::result_type gen() { return dist(eng); }
         RNG(double min,double max,int seed)
         : dist(min,max)
         {eng.seed(seed); }
    };
    

    Live demo

    【讨论】:

    • 谢谢,@Praetorian!我唯一需要添加到您的建议的是将“::random”添加到 uniform_real_distribution 的命名空间。像这样: typedef boost::random::uniform_real_distribution DIST;您同意将此添加到您的答案中以便我接受吗?
    • @CharlesSantana 首先,欢迎来到 SO,创建 SSCCE 非常棒。我最初的typedef 是不正确的,部分问题是在没有先编译的情况下在答案中输入代码:)
    猜你喜欢
    • 2013-11-09
    • 1970-01-01
    • 2014-04-02
    • 2011-01-16
    • 2013-12-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多