C ++在多个对象中提升正常随机数

时间:2013-11-13 13:51:40

标签: c++ boost c++11 random normal-distribution

对不起,如果这是愚蠢的。我是Boost的新手,并且很长一段时间没有使用过C ++。这是一个试图回到它的玩具问题。

假设我有 n 老虎机,每次运行都支付 R R 需要正常分发。每台机器的均值和方差需要不同。我当前的C ++ 11代码如下所示:

narm.h:

class narm
{
public:
    narm(int mean, int var); // Constructor takes mean and variance

    double mean;             // Local Mean
    double variance;         // Local Var
    static int counter;      // Static Counter for the number of objects so far
    int num;                 // Which machine am I

    boost::mt19937 random_number_generator;
    boost::normal_distribution<> normal;
    boost::variate_generator<boost::mt19937&,boost::normal_distribution<> > var_nor;
};

narm.cpp

// Static variable
int narm::counter = 0;

// Constructor. Creates the mt19937 generator and normal distribution.
// Then make the generator.
narm::narm(int mean, int var) : random_number_generator(), normal(mean, var), var_nor(random_number_generator, normal)
{
    this->mean = mean;
    this->variance = var;
    num = counter++;

    // Seed the generator. The num is also used, as the constructors
    //    were called so fast that std::time was the same (correct solution?)
    var_nor.engine().seed(std::time(NULL) + getpid() + num );
    // I'm not entirely sure what this does.
    var_nor.distribution().reset();

    // Get random number
    std::cout << num << " : " << var_nor() << std::endl;
}

我将使用play()函数返回随机数。

我有几个问题。

  1. 我有点担心我的种子。我确信没有一个种子与构造函数从0到n-1的顺序都是一样的。因此,std::timenum都会不断增加。还有什么我需要担心的吗?
  2. 我没有在初始化程序中播种mt19937对象,因为我还没有num
  3. 主要问题

    是否可以使用所有这些不同的随机数生成器,还是应该使用在所有对象之间共享的单个生成器?如果共享一个更好,我如何处理每个对象的不同均值/方差值?

    谢谢!


    更新

    以下是基于您的评论/答案的更新:

    narm.h

    #include<random>
    
    class narm
    {
    public:
        narm(int mean, int var);
    
        int k;
        int num;
    
        double mean;
        double variance;
    
        static int counter;
        static std::random_device rd;  // Shared
        static std::mt19937 generator; // Shared
    
        std::normal_distribution<> distribution;
    };
    

    narm.cpp

    #include "narm.h"
    #include <random>
    #include <iostream>
    
    int narm::counter = 0;
    
    std::random_device narm::rd;
    std::mt19937 narm::generator(rd());
    
    narm::narm(int mean, int var) : k(0), num(counter++), distribution(mean, var)
    {
        this->mean = mean;
        this->variance = var;
    
        std::cout << num << " : " << distribution(generator) << std::endl;
    }
    

1 个答案:

答案 0 :(得分:1)

  

我有点担心我的种子。

由于你说你正在使用C ++ 11,你可以从std::random_device播种生成器,如果可能的话,它将使用真正的随机源,否则给予(希望)好的伪随机数。

(顺便说一下,如果您使用的是C ++ 11,那么现在所有这些都在标准的<random>库中,因此不需要Boost)。

  

我没有在初始化程序中播种mt19937对象,因为我还没有num。

您可以更改成员顺序,以便首先初始化num。当然,如果您使用std::random_device,则无关紧要。

  

是否可以使用所有这些不同的随机数生成器,还是应该使用在所有对象之间共享的单个生成器?

随机性可能并不差,但我不足以说明这些事情的专家。它似乎相当浪费,因为每个发生器都有几千字节的状态。

  

如果共享一个更好,我如何处理每个对象的不同均值/方差值?

您可以使用不同的distrubutions但使用相同的底层生成器来生成多个variate生成器。

警告:请勿在真正的赌博机中使用此功能。 Mersenne Twister生成器不适用于加密,如here所述。