Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What's the standard way for getting uniformly distributed random integers in C++?

Tags:

c++

random

Is there a function for obtaining uniformly distributed pseudo-random integers in some specified range? I could write my own function using rand, but this seems like a common enough situation that there's probably something in the STL for it.

like image 611
Andreas Avatar asked May 22 '12 22:05

Andreas


2 Answers

Boost provides many tools for random number generation. For uniform distributions you have this one:

http://www.boost.org/doc/libs/1_49_0/doc/html/boost/random/uniform_real_distribution.html

EDIT: updated to include the new C++11 implementation. For the case of integers, here you have the reference:

http://en.cppreference.com/w/cpp/numeric/random/uniform_int_distribution

A simple example would be:

#include <random>
#include <iostream>
int main()
{
    std::random_device rd;
    std::mt19937 gen(rd());
    std::uniform_int_distribution<> dis(1, 6);
    for(int n=0; n<10; ++n)
        std::cout << dis(gen) << ' ';
    std::cout << '\n';
}
like image 108
betabandido Avatar answered Oct 13 '22 09:10

betabandido


To generate pseudo-random numbers in C++, a very good option is using the Mersenne twister pseudo-random number generator engine: std::mt19937 from the <random> header.

We can think of this engine as a black-box that spits out high-quality random bits.

Then, these random bits can be shaped in some integers output using a distribution; in particular, to get uniformly distributed pseudo-random numbers, a std::uniform_int_distribution can be used.

Note that the engine object must be initialized with a seed.
std::random_device can be used for that purpose.

So, this process can be summarized in three logical steps:

  1. Create an instance of std::random_device, to get a non-deterministic seed for the Mersenne twister engine.
  2. Create an instance of std::mt19937 engine, to get high-quality pseudo-random bits.
  3. Use a std::uniform_int_distribution to shape these random bits in uniformly-distributed integers.

Compilable C++ code follows:

#include <iostream>     // for console output
#include <random>       // for pseudo-random number generators and distributions

int main()
{
    // Use random_device to generate a seed for Mersenne twister engine.
    std::random_device rd;    

    // Use Mersenne twister engine to generate pseudo-random numbers.
    std::mt19937 engine(rd());
    
    // "Filter" MT engine's output to generate pseudo-random integer values,
    // **uniformly distributed** on the closed interval [0, 99].  
    // (Note that the range is [inclusive, inclusive].)
    std::uniform_int_distribution<int> dist(0, 99);

    // Generate and print 10 pseudo-random integers
    for (int i = 0; i < 10; ++i)
    {
        std::cout << dist(engine) << ' ';
    }
    std::cout << std::endl;
}

For more details on generating pseudo-random numbers in C++ (including reasons why rand() is not good), see this video by Stephan T. Lavavej (from Going Native 2013):

rand() Considered Harmful

like image 43
Mr.C64 Avatar answered Oct 13 '22 09:10

Mr.C64