C++ 生成随机数
一般来说,网上绝大多数的关于C++生成随机数的文章,写的都是使用C语言的 rand()
来生成的,比如像下面这样:
#include <stdio.h> #include <stdlib.h> #include <time.h> int main(void) { srand(time(NULL)); // use current time as seed for random generator int random_variable = rand(); printf("Random value on [0,%d]: %d\n", RAND_MAX, random_variable); // roll a 6-sided die 20 times for (int n=0; n != 20; ++n) { int x = 7; while(x > 6) x = 1 + rand()/((RAND_MAX + 1u)/6); // Note: 1+rand()%6 is biased printf("%d ", x); } }
可能的输出:
Random value on [0,2147483647]: 448749574 3 1 3 1 4 2 2 1 3 6 4 4 3 1 6 2 3 2 6 1
rand()
生成一个在 [0, RAND_MAX
] 之间的伪随机数。使用 srand()
可以设置随机数种子,如果没有设置随机数种子,那么程序每次运行得到的多个随机数应该是相同的。所以一般情况下都会设置当前时间为随机数种子 srand(time(NULL));
这是C语言中产生随机数的方法,C++ 从 C++11 标准加入了产生随机数的标准库 random
,如果使用 C++ 产生随机数,可能的代码如下:
#include <iostream> #include <iomanip> #include <string> #include <map> #include <random> #include <cmath> int main() { // Seed with a real random value, if available std::random_device r; // Choose a random mean between 1 and 6 std::default_random_engine e1(r()); std::uniform_int_distribution<int> uniform_dist(1, 6); int mean = uniform_dist(e1); std::cout << "Randomly-chosen mean: " << mean << '\n'; // Generate a normal distribution around that mean std::seed_seq seed2{r(), r(), r(), r(), r(), r(), r(), r()}; std::mt19937 e2(seed2); std::normal_distribution<> normal_dist(mean, 2); std::map<int, int> hist; for (int n = 0; n < 10000; ++n) { ++hist[std::round(normal_dist(e2))]; } std::cout << "Normal distribution around " << mean << ":\n"; for (auto p : hist) { std::cout << std::fixed << std::setprecision(1) << std::setw(2) << p.first << ' ' << std::string(p.second/200, '*') << '\n'; } }
可能的输出:
Randomly-chosen mean: 4 Normal distribution around 4: -4 -3 -2 -1 0 * 1 *** 2 ****** 3 ******** 4 ********* 5 ******** 6 ****** 7 *** 8 * 9 10 11 12
一般情况下,获取随机数都往往希望从某个区间里,均匀的选取,但是一些情况下,需要模拟随机变量,C++11 标准里有多种随机分布:
- 均匀分布
- 伯努利分布
- 泊松分布
- 正态分布
- 抽样分布
不过绝大多数情况下,需要的功能可能如下:
#include <random> #include <iostream> int main() { std::random_device rd; //Will be used to obtain a seed for the random number engine std::mt19937 gen(rd()); //Standard mersenne_twister_engine seeded with rd() std::uniform_int_distribution<> dis(1, 6); for (int n=0; n<10; ++n) //Use dis to transform the random unsigned int generated by gen into an int in [1, 6] std::cout << dis(gen) << ' '; std::cout << '\n'; }
评论