Boost C++ Libraries

...one of the most highly regarded and expertly designed C++ library projects in the world. Herb Sutter and Andrei Alexandrescu, C++ Coding Standards

Click here to view the latest version of this page.
PrevUpHomeNext

Tutorial

Generating integers in a range
Generating integers with different probabilities

For the source of this example see die.cpp. First we include the headers we need for mt19937 and uniform_int.

#include <boost/random/mersenne_twister.hpp>
#include <boost/random/uniform_int.hpp>
#include <boost/random/variate_generator.hpp>

We use mt19937 with the default seed as a source of randomness. The numbers produced will be the same every time the program is run. One common method to change this is to seed with the current time (std::time(0) defined in ctime).

boost::mt19937 gen;

[Note] Note

We are using a global generator object here. This is important because we don't want to create a new pseudo-random number generator at every call

Now we can define a function that simulates an ordinary six-sided die.

int roll_die() {
    1boost::uniform_int<> dist(1, 6);
    2boost::variate_generator<boost::mt19937&, boost::uniform_int<> > die(gen, dist);
    3return die();
}

1

mt19937 produces integers in the range [0, 232-1]. However, we want numbers in the range [1, 6]. The distribution uniform_int performs this transformation.

[Warning] Warning

Contrary to common C++ usage uniform_int does not take a half-open range. Instead it takes a closed range. Given the parameters 1 and 6, uniform_int can can produce any of the values 1, 2, 3, 4, 5, or 6.

2

variate_generator combines a generator with a distribution.

[Important] Important

We pass boost::mt19937& to variate_generator instead of just boost::mt19937 (note the reference). Without the reference, variate_generator would make a copy of the generator and would leave the global gen unchanged. Consequently, roll_die would produce the same value every time it was called.

3

A variate_generator is a function object.

For the source of this example see weighted_die.cpp.

#include <boost/random/mersenne_twister.hpp>
#include <boost/random/uniform_real.hpp>
#include <boost/random/variate_generator.hpp>
#include <vector>
#include <algorithm>
#include <numeric>

boost::mt19937 gen;

This time, instead of a fair die, the probability of rolling a 1 is 50% (!). The other five faces are all equally likely.

static const double probabilities[] = {
    0.5, 0.1, 0.1, 0.1, 0.1, 0.1
};

Now define a function that simulates rolling this die. Note that the C++0x library contains a discrete_distribution class which would be a better way to do this.

int roll_weighted_die() {
    std::vector<double> cumulative;
    std::partial_sum(&probabilities[0], &probabilities[0] + 6,
                     std::back_inserter(cumulative));
    boost::uniform_real<> dist(0, cumulative.back());
    boost::variate_generator<boost::mt19937&, boost::uniform_real<> > die(gen, dist);
    1return (std::lower_bound(cumulative.begin(), cumulative.end(), die()) - cumulative.begin()) + 1;
}

1

Find the position within the sequence and add 1 (to make sure that the result is in the range [1,6] instead of [0,5])


PrevUpHomeNext