本文是C++11新特性介绍的第七部分,涉及到随机数库相关的新特性。
简介
之前,C++中的随机数生成都依赖于一个简单的rand函数。这个函数产生一定范围内的一个均匀随机整数。如果需要其他随机分布或者其他范围的随机数,就需要根据rand函数产生的随机数进行再加工,不过这时,就容易引入非随机性了。
C++11新标准中引入了一个新的随机数库,相关功能定义在random头文件中,通过多个互相协作的类,可以生成任意范围内、服从多种随机分布的随机数。
随机引擎
新的随机数库中引入了随机引擎的概念。一个随机引擎将产生一组原始的随机数列,一般这些原始的随机数不能直接使用,要配合随机分布类产生符合某分布的随机数后才能进行使用。
默认随机
一般,最常用的随机引擎是default_random_engine。
1 2 3 4 5 6 7 8 9
| std::cout<<"test default random engine:\n"; std::default_random_engine e; e.seed(time(0)); for(size_t i = 0; i < 10; i++) { std::cout<<e()<<'\t'; } std::cout<<'\n'; std::cout<<"test default random engine done.\n"<<std::endl;
|
随机分布
可以用uniform_int_distribution和随机引擎配合来产生均匀分布的随机整数。
1 2 3 4 5 6 7 8 9
| std::cout<<"test random distribution:\n"; e.seed(time(0)); std::uniform_int_distribution<unsigned> u(0, 9); for(size_t i = 0; i < 10; i++) { std::cout<<u(e)<<'\t'; } std::cout<<'\n'; std::cout<<"test random distribution done.\n"<<std::endl;
|
均匀分布
类似的,uniform_real_distribution则可以产生一个均匀分布的实数。
1 2 3 4 5 6 7 8 9
| std::cout<<"test real distribution:\n"; e.seed(time(0)); std::uniform_real_distribution<double> u2(0, 1); for(size_t i = 0; i < 10; i++) { std::cout<<u2(e)<<'\t'; } std::cout<<'\n'; std::cout<<"test real distribution done.\n"<<std::endl;
|
正态分布
换一个分布,试试正态分布。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| std::cout<<"test normal distribution:\n"; e.seed(time(0)); std::normal_distribution<> n(4, 1.5); std::vector<unsigned> vals(9); for(size_t i = 0; i < 250; i++) { unsigned v = lround(n(e)); if(v < vals.size()) vals[v]++; } for(size_t i = 0; i < vals.size(); i++) { std::cout<<i<<": "<<std::string(vals[i], '*')<<std::endl; } std::cout<<"test normal distribution done.\n"<<std::endl;
|
伯努利分布
伯努利分布也是经常会使用到的:
1 2 3 4 5 6 7 8 9 10 11 12
| std::cout<<"test bernoulli distribution:\n"; e.seed(time(0)); std::bernoulli_distribution b(0.7); std::vector<unsigned> bers(2); for(size_t i = 0; i < 200; i++) { if(b(e)) bers[1]++; else bers[0]++; } std::cout<<"True: "<<bers[1]<<std::endl; std::cout<<"False: "<<bers[0]<<std::endl; std::cout<<"test bernoulli distribution done.\n";
|
输出
整个测试程序的输出结果如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27
| test default random engine: 1446291605 455604842 1571377939 395129967 929918845 1907528696 51427609 1055398369 2012947210 146383632 test default random engine done. test random distribution: 6 2 7 1 4 8 0 4 9 0 test random distribution done. test real distribution: 0.212158 0.183997 0.888262 0.491458 0.0681652 0.173643 0.128234 0.954471 0.891836 0.912416 test real distribution done. test normal distribution: 0: ** 1: ******** 2: ****************************** 3: ************************************************* 4: ***************************************************************** 5: ******************************************************* 6: ***************************** 7: ********* 8: * test normal distribution done. test bernoulli distribution: True: 132 False: 68 test bernoulli distribution done.
|
总结
1.C++11新标准中引入了比rand更强大的随机数库。
2.随机数引擎和随机分布类配合,共同产生符合某一分布、在某一范围内的随机数。