| Home | Libraries | People | FAQ | More

## Tutorial

### Generating integers in a range

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
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() {
        boost::uniform_int<> dist(1, 6);
        boost::variate_generator<boost::mt19937&, boost::uniform_int<> > die(gen, dist);
        return die();
    }

| `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
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.
| `variate_generator` combines a generator with a distribution.
| 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.
| A `variate_generator` is a function object.

### Generating integers with different probabilities

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);
        return (std::lower_bound(cumulative.begin(), cumulative.end(), die()) - cumulative.begin()) + 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])