This article mainly refers to from a blog post and Cplusplus and cppreferrence. The blog post is a translation of the pseudo-random number on the Cplusplus, which is referred to in the following section.
1. Pseudo-random number generation function in C language
2. Pseudo-random number generator in C + + language
Pseudo-random number library in C + + the random is c++11 only started to add. It allows us to combine generators (generators) and distributor (distributions) to generate pseudo-random numbers.
Generator (generators):can produce discrete values of equal potential distributions.
Distributor (distributions):The uniform distribution value that can be generated by the generatorMappingTo a variety of otherDistribution, such as evenly distributed uniform, normal distribution normal, two distribution binomial, Poisson distribution poisson. 2.1 A simple example below is a simple example:
1#include <iostream>2#include <random>3 using namespacestd;4 5 intMain ()6 {7 default_random_engine Generator;8uniform_int_distribution<int> Dis (0,6);9 for(inti =0; I <6; i++)Ten { OneStd::cout << dis (generator) << Std::endl;//1 0 1 1 2 6 A } - - return 0; the}
View Code
If we are too bothered to pass in the generator object every time, we can use Std::bind to bind the generator object and the Distributor object (note that bind is in the header file functional). As shown below:
1#include <iostream>2#include <random>3#include <functional>//Std::bind4 using namespacestd;5 6 intMain ()7 {8 default_random_engine Generator;9uniform_int_distribution<int> Dis (0,6);TenAuto Dice =bind (dis, generator); One for(inti =0; I <6; i++) A { -Std::cout << Dice () << Std::endl;//1 0 1 1 2 6 - } the - return 0; -}
View Code
In fact, we will find the above two code results no matter how many times it is the same, very strange! We can try to give the generator a seed, as follows:
1#include <iostream>2#include <random>3#include <functional>//Std::bind4 using namespacestd;5 6 intMain ()7 {8Default_random_engine Generator (Ten);//seed = Ten9uniform_int_distribution<int> Dis (0,6);TenAuto Dice =bind (dis, generator); One for(inti =0; I <6; i++) A { -Std::cout << Dice () << Std::endl;//2 0 4 1 2 4 - } the - return 0; -}
View Code
Now we see the results are different. But no matter how many times we run, the result is the same, which is even more strange. The reason is that the seeds we set are fixed. For a computer, the output must be deterministic when the input is determined. Because both the generator algorithm and the distributor algorithm are deterministic, the output must be deterministic when the input is deterministic. Therefore, in order to get a different result, we can use the system time as a seed:
1#include <iostream>2#include <random>3#include <functional>//Std::bind4#include"time.h" // Time5 using namespacestd;6 7 intMain ()8 {9 Default_random_engine Generator (Time (NULL));Tenuniform_int_distribution<int> Dis (0,6); OneAuto Dice =bind (dis, generator); A for(inti =0; I <6; i++) - { -Std::cout << Dice () <<Std::endl; the } - - return 0; -}
View Code2.2 About generators and distributions
Refer to the Cplusplus Manual for generator and distributor.
Below is an example from Cppreferrence:
1#include <iostream>2#include <iomanip>3#include <string>4#include <map>5#include <random>6#include <cmath>7 using namespacestd;8 9 intMain ()Ten { One //Seed with a real random value, if available A Std::random_device Rd; -cout << Rd () <<Endl; - //Choose A random mean between 1 and 6 the std::d efault_random_engine E1 (RD ()); -std::uniform_int_distribution<int> Uniform_dist (1,6); - intmean =Uniform_dist (E1); -Std::cout <<"Randomly-chosen mean:"<< mean <<'\ n'; + - //Generate A normal distribution around that mean + std::mt19937 E2 (RD ()); AStd::normal_distribution<> normal_dist (Mean,2);//default:double at -std::map<int,int>hist; - for(intn =0; N <10000; ++N) { -++Hist[std::round (Normal_dist (E2))]; - } -Std::cout <<"Normal distribution around"<< mean <<": \ n"; in for(Auto p:hist) { -Std::cout << std::fixed<< Std::setprecision (1) << STD::SETW (2) to<< P.first <<' '<< std::string(P.second/ $,'*') <<'\ n'; + } - the return 0; *}
View Code
We can see that the above example uses the random_device generator. The generator produces a non-deterministic random number. In the implementation of Linux, is to read/dev/urandom device, in the implementation of Windows is actually using rand_s. The Random_device provides the () operator, which returns a number between min () and Max () (min (), Max () is the generator member function). In the case of Linux (like or Unix), this can be used to produce high-quality random numbers, which can be understood as true random numbers.
An example is as follows:
1 //Random_device Example2#include <iostream>3#include <random>4 5 intMain ()6 {7 Std::random_device Rd;8 9Std::cout <<"default Random_device characteristics:"<<Std::endl;TenStd::cout <<"Minimum:"<< rd.min () <<Std::endl; OneStd::cout <<"Maximum:"<< Rd.max () <<Std::endl; AStd::cout <<"Entropy:"<< rd.entropy () <<Std::endl; -Std::cout <<"a random number:"<< Rd () <<Std::endl; - the return 0; -}
View Code
The possible outputs are:
1 default Random_device Characteristics: 2 0 3 4294967295 4 + 5 4230014324
View Code
In some cases, random_device are often used to generate seeds, as they take time as seeds.
How to generate pseudo-random numbers in C/