質問

Sorry if this is stupid. I'm new to Boost and haven't used C++ for a long time. This a toy problem trying to get back into it.

Suppose I have n slot machines that pay out R on each run. R needs to be distributed normally. The mean and variance needs to be different for each machine. My current C++11 code looks like this:

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;
}

I'll have a play() function that just returns the random number.

I have a few side questions.

  1. I'm a little worried about my seeds. I'm convinced that none of the seed will be the same as the constructors are called in order from 0 to n-1. So both std::time and num are always increasing. Is there anything else I need to worry about here?
  2. I haven't seeded the mt19937 object in the initializer because I don't have num yet.

Main Question

Is it ok to have all these different random number generators or should I be using a single one that's shared between all the objects? If sharing a single one is better, how do I handle the different mean/variance values for each object?

Thanks!


Update

Here are the following updates based on your comments/answers:

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;
}
役に立ちましたか?

解決

I'm a little worried about my seeds.

Since you say you're using C++11, you could seed the generator from std::random_device, which will use a source of true randomness if possible, and give (hopefully) good pseudorandom numbers otherwise.

(By the way, if you're using C++11, then all of this is now in the standard <random> library, so there's no need for Boost).

I haven't seeded the mt19937 object in the initializer because I don't have num yet.

You could change the member order so that num is initialised first. Of course, that's irrelevant if you use std::random_device.

Is it ok to have all these different random number generators or should I be using a single one that's shared between all the objects?

The randomness is probably no worse, but I'm not enough of an expert in such things to say for sure. It does seem rather wasteful, since each generator has a few kilobytes of state.

If sharing a single one is better, how do I handle the different mean/variance values for each object?

You can have multiple variate generators using different distrubutions but the same underlying generator.

WARNING: don't use this in a real gambling machine. The Mersenne Twister generator is not suitable for cryptography, as described here.

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top