随机数
前言
使用c++时经常要用到随机数, 本文对c++的随机数api做个简单的总结
传统方法
c++11之前一般会用srand()
配合rand()
来实现随机数的使用
比如
1 | for (int i=0; i<10;i++) |
1 | for (int i=0; i<10;i++) |
1 | for (int i=0; i<10;i++) |
c++11随机数算法
c++11提供了3个新的随机算法
- linear_congruential_engine线性同余法
- mersenne_twister_engine梅森旋转法
- substract_with_carry_engine滞后Fibonacci
借用网络图用一下
如果我们要使用这三个模板类的话,就必须自己实例化之。但这些实例化参数都是这些算法里面使用到的参数,如果不懂算法的原理的话,真的不知道需要用什么参数才能得到比较好的随机序列。所以我们这些卑微的码农是用不了这些模板类的。C++11标准也想到了这点,所以就帮我们预定义了一些随机数类,这些随机数类都是用比较好的参数实例化上面那三个模板类。注意:在C++11里面,把这些随机数生成器叫做引擎(engines)。
直接开撸
1 | std::default_random_engine random; |
结果就不显示了, 一堆随机数
同样的, 也可以设置随机种子(seed),方法是往构造函数传入参数或者使用 random.seed()
来设置
1 | std::default_random_engine random(1); |
1 | std::default_random_engine random; |
用上述两个模板类来生成的均是均匀分布的随机数, 基本已经能满足一般的项目需求了
需要注意的是
uniform_int_distribution的随机数的范围是
[ ]
uniform_real_distribution却是半开范围
[ )
如果需要浮点数随机范围是
[]
,那么按照如下使用
1 std::uniform_real_distribution<double> dis2(0, std::nextafter(1,DBL_MAX));
其他算法
C++11提供的概率分布类型有下面这些:
均匀分布:
uniform_int_distribution 整数均匀分布
uniform_real_distribution 浮点数均匀分布
伯努利类型分布:(仅有yes/no两种结果,概率一个p,一个1-p)
bernoulli_distribution 伯努利分布
binomial_distribution 二项分布
geometry_distribution 几何分布
negative_biomial_distribution 负二项分布
Rate-based distributions:
poisson_distribution 泊松分布
exponential_distribution指数分布
gamma_distribution 伽马分布
weibull_distribution 威布尔分布
extreme_value_distribution 极值分布
正态分布相关:
normal_distribution 正态分布
chi_squared_distribution卡方分布
cauchy_distribution 柯西分布
fisher_f_distribution 费歇尔F分布
student_t_distribution t分布
分段分布相关:
discrete_distribution离散分布
piecewise_constant_distribution分段常数分布
piecewise_linear_distribution分段线性分布
泊松分布
1 | std::default_random_engine random; |
上图显示的就是如下图的情况