Random Engine in Modern C++

Random numbers are widely used in different applications. For example, when you are playing a video game, and some random event like weather changes from a sunny day to a rainy day, we might need to be able to generate the random number in order to determine whether we need to have the weather change. In C language, we can easily generate a pseudo-random number through a rand() function call. The following code will provide us with a random number between 1 – 10, inclusively:

/* initialize random seed: */
srand (time(NULL));
/* generate secret number between 1 and 10: */
iSelect = rand() % 10 + 1;

If we do not really care about the distribution of the random number, the above approach is acceptable. If we care about the distribution, we need to consider another approach. The reason is that rand() is good to generate a uniformly distributed random number between 0 and RAND_MAX, however, if we do the modular operation, does the random number still remain uniformly distributed? No. So in this article, we will introduce the random engine and distribution objects in the <random> library of C++ and see how we can apply them.

First, let’s look at the random engine. A random engine is a stateful generator that generates random values within predefined min and max. We cannot change the range here. Not truly random — pseudorandom (which is pretty similar to rand() in terms of pseudorandom)! Please take a look at the following code with comments to see how we can define and use random engine:

This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.

 #include #include #include #include #include #include using namespace std; void printRandom(default_random_engine e){ for(int i = 0; i < 10; i++) cout << e() << " "; cout << endl; } int main(){ //Define the default random engine. default_random_engine eng; //generate two random numbers cout << "random number 1:" << eng() <> eng; //restore the state we have saved. //Now the number 5 and 6 will be exactly the same as number 3 and 4 cout << "random number 5:" << eng() < d = {1, 2, 3, 4, 5, 6, 7, 8, 9}; shuffle(d.begin(), d.end(), default_random_engine()); for (int num : d) { cout << num << " "; } cout << endl; system("pause"); return 0; }

Note we generally utilize chrono library to generate the seed for the random engine, for more detail about the chrono library, please refer to here.  C++ standard template library provides 16 different engine types. The default engine is a balanced random number generator, with reasonable cost and randomization.

Now, let’s take a look at the distribution objects in <random> library. Suppose we want to generate a number between 1 – 5 uniformly,  what can we do? Please take a look at the following code, you will know how to do it.

This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.