c++ -11中使用boost封装的随机数生成器

Encapsulated Random number generator in C++-11 using boost

本文关键字:封装 随机数生成器 boost c++      更新时间:2023-10-16

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

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

我实现了下面的代码。但它在两个方面都失败了:随机种子的改变和取值范围的定义。
#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);
}

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

boost::variate_generator按值接受其构造函数参数,因此当您在mem初始化列表中传递给它默认构造的mt19937时,它会复制它。在构造函数的主体中播种引擎将不会对该副本产生影响。要解决这个问题,将模板参数类型更改为引用。

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

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

您可能正在寻找的分布是uniform_real_distribution

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

在做了这些修复之后,你的代码应该像你想要的那样运行。

现场演示


对于c++ 11编译器,你甚至不需要Boost来做这些,<random>头文件提供了你需要的所有组件。唯一重要的区别是缺少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); }
};

现场演示