std::mt19937 Class in C++
std::mt19937(since C++11) class is a very efficient pseudo-random number generator and is defined in a random header file. It produces 32-bit pseudo-random numbers using the well-known and popular algorithm named Mersenne twister algorithm. std::mt19937 class is basically a type of std::mersenne_twister_engine class.
typedef mersenne_twister_engine<uint_fast32_t, 32,624,397,31,0x9908b0df,11,0xffffffff,7,0x9d2c5680,15,0xefc60000,18,1812433253> mt19937;
Syntax :
mt19937 mt1(seed_value);
Here mt1 is an instance of the mt19937 class and it takes a seed value to generate an entire sequence.
Significance Of The Name mt19937
mt19937 stands for mersenne twister with a long period of 219937 - 1 which means mt19937 produces a sequence of 32-bit integers that only repeats itself after 219937 - 1 number have been generated.
Similarities Between mt19937 And rand() & srand():
The std::mt19937 does two things -
- When an std::mt19937 object is instantiated, it takes an argument which is used to generate seed value(like srand()).
- By using operator(), it generates a random number (like rand()).
Below is the example to demonstrate the similarities:
// C++ program for demonstrating
// similaritites
#include <ctime>
#include <iostream>
#include <random>
using namespace std;
int main()
{
// Initializing the sequence
// with a seed value
// similar to srand()
mt19937 mt(time(nullptr));
// Printing a random number
// similar to rand()
cout << mt() << '\n';
return 0;
}
Output
3529725061
Being a type of std::mersenne_twister_engine class it has the same member functions which mersenne_twister_engine does. Here is the list of some important member functions -
1. (constructor): constructs the mt19937 object. It takes either a seed value of result type or a seed sequence object(Similar to srand() function).
Example :
// C++ program to implement
// the above concept
// This header file is
// for time
#include <ctime>
#include <iostream>
#include <random>
using namespace std;
int main()
{
// Using the constructor to
// initialize with a seed value
mt19937 mt(time(nullptr));
// Operator() is used to
// generate random numbers
cout << mt() << '\n';
return 0;
}
Output
3529725061
2. min(): returns the minimum value operator() can return (which is zero).
Example:
// C++ program for the
// min()
#include <ctime>
#include <iostream>
#include <random>
using namespace std;
// Driver code
int main()
{
// Initializing mt19937
// object
mt19937 mt(time(nullptr));
// Prints the minimum value
// which is 0
cout << "the minimum integer it can generate is " <<
mt.min() << endl;
return 0;
}
Output
the minimum integer it can generate is 0
3. max(): returns maximum value operator() can return ( which is 232 - 1 = 4294967295 )
Example :
// C++ program to demonstrate
// max()
#include <ctime>
#include <iostream>
#include <random>
using namespace std;
// Driver code
int main()
{
// Initializing mt19937
// object
mt19937 mt(time(nullptr));
// Prints the maximum value
// which is 4294967295
cout << "mt19937 can generate random numbers upto " <<
mt.max() << endl;
return 0;
}
Output
mt19937 can generate random numbers upto 4294967295
4. seed(): reinitializes the seed value of the object either by taking a seed value of result type or by taking a seed sequence object.
Example :
// C++ program to demonstrate
// seed()
#include <iostream>
#include <random>
using namespace std;
// Driver code
int main()
{
// Defining the
// mt19937 object
mt19937 mt;
// Initializing a random
// sequence with a seed value
mt.seed(45218965);
cout << "some random numbers generated by mt19937 are:" <<
endl;
for (int i = 5; i > 0; i--)
{
cout << mt() << ' ';
}
return 0;
}
Output
some random numbers generated by mt19937 are: 3334444225 240363925 3350157104 146869560 639267854
5. operator(): it generates pseudo-random integers.(similar to rand() function).
Example:
// C++ program to demonstrate
// operator()
#include <ctime>
#include <iostream>
#include <random>
using namespace std;
// Driver code
int main()
{
// Initializing mt19937
// object
mt19937 mt(time(nullptr));
for (int i = 0; i < 5; i++)
{
// operator() is used to
// generate random numbers
cout << mt() << ' ';
}
return 0;
}
Output
3529725061 3019704141 2006641117 725527349 3631905871
There are also non-member functions overloaded to work with std::mt19937 object. These are -
- operator<<() - This is overloaded so that we can directly print the value generated by the mt19937 object to the output stream.
- operator>>() - it is used to extract seed value from input.
Here is a simple example to generate a pseudo-random number by taking a seed value from the user -
Using operator<<() and operator>>() :
Example :
// C++ program to demonstrate
// operator>>() and <<operator()
#include <ctime>
#include <iostream>
#include <random>
using namespace std;
// Driver code
int main()
{
mt19937 mt;
cout << "enter a integer to begin" <<
endl;
// operator>>() is used to get
// a seed value from the user
cin >> mt;
// <<operator() is used to print
// the random integer
cout << "a random number " <<
mt() << " is generated";
return 0;
}
Output
enter a integer to begin a random number 3499211612 is generated
Why Use mt19937 Instead Of rand() ?
Although the rand() function can be used in a small range, it is inefficient for generating real-world like random numbers. A careful person can observe the repetitions of the random numbers generated by rand() which is very risky. Whereas std::mt19937 has the following advantages -
- It has a very long period compared to the rand(). It will take a longer time. If an implementation of the Mersenne twister could generate 1,000,000,000 (one billion) pseudo-random numbers every second, a program that generated pseudo-random numbers would need to run about 1.3684 Ã 105,985 years to repeat the random sequence. So it is safe to assume that an observer will never guess the number.
- Many random number generators can be initiated simultaneously with different seed values. Here is an example -
// C++ program to demonstrate
// above approach
#include <iostream>
#include <random>
using namespace std;
// Driver code
int main()
{
mt19937 mt1(10000);
mt19937 mt2(100000);
cout << mt1() << endl;
cout << mt2() << endl;
return 0;
}
Output
2342776460 1235064505