【C++11】随机数函数库random
来源:互联网 发布:pdf分割软件 编辑:程序博客网 时间:2024/04/28 14:09
1.随机数由生成器和分布器结合产生
生成器generator:能够产生离散的等可能分布数值
分布器distributions: 能够把generator产生的均匀分布值映射到其他常见分布,如均匀分布uniform,正态分布normal,二项分布binomial,泊松分布poisson
2.分布器利用运算符()产生随机数,要传入一个generator对象作为参数
std::default_random_engine generator; std::uniform_int_distribution<int> dis(0,100); for(int i=0;i<5;i++) { std::cout<<dis(generator)<<std::endl; }
如果嫌每次调用都要传入generator对象麻烦,可以使用std::bind,要包含头文件functional
auto dice = std::bind(distribution,generator)以后就可以直接调用dice()产生复合均匀分布的随机数。但是多次运行上例会发现每次产生的随机数序列都一样,因为没有设定种子(同cstdlib库中的rand和srand关系)
std::default_random_engine generator; std::uniform_int_distribution<int> dis(0,100); auto dice= std::bind(dis,generator); for(int i=0;i<5;i++) { std::cout<<dice()<<std::endl; }
3.种子
除了random_device生成器(真随机数生成器或叫f非确定性随机数生成器)以外(linux中有效,windows下其实也是伪随机),所有在库中定义的随机数引擎都是伪随机数生成器,他们都利用了特定的算法实现,这些生成器都需要一个种子。种子可以是一个数值,或者是一个带有generate成员函数的对象。简单的应用中,用time作种子即可。
说明:如果不设定种子,那么产生的随机数序列每次都一样,如上代码,产生5个1到6之间的随机数,但是每次都是82 13 91 84 12
改为如下代码,可以使每次产生的随机数序列不同:
std::default_random_engine generator(time(NULL)); std::uniform_int_distribution<int> dis(0,100); auto dice= std::bind(dis,generator); for(int i=0;i<5;i++) { std::cout<<dice()<<std::endl; }
4.关于生成器
C++11标准提供了三个生成器模版类可以实例化为生成器,但需要有一定的数学功底才懂得每个模版参数的意义,可参照算法出处的论文。
这三个生成器类模版为:
linear_congruential_engine 线性同余法mersenne_twister_engine 梅森旋转法substract_with_carry_engine滞后Fibonacci
线性同余法举例
template <class UIntType, UIntType a, UIntType c, UIntType m>class linear_congruential_engine;
第一个参数:生成器类型unsigned int,unsigned long等
第二到第四个参数:是线性同余法公递推公式Nj+i =(AxNj+C) (mod M)里的三个常数值A,C,M
要求:如果m不为0,a,c的值要小于m
如一会介绍的常用生成器:
typedef linear_congruential<unsigned long, 16807, 0, 2147483647> minstd_rand0; typedef linear_congruential<unsigned long, 48271, 0, 2147483647> minstd_rand;
可见如果自己实例化模版类很麻烦,需要很强的数序知识,所以有几个常用的几个模版实例化生成器,他们都是需要一个种子参数就可以:
4.1线性同余法:
minstd_rand()minstd_rand0
利用适配器变种后的线性同余法
knuth_b minstd_rand0 with shuffle_order_engine
4.2梅森旋转法:
default_random_engine()mt19937mt19937_64
4.3滞后Fibonacci法
ranlux24_baseranlux48_base
利用适配器变种后的滞后Fibonacci法:
ranlux24 ranlux24_base with discard_block_engineranlux48 ranlux48_base with discard_block_engine
三个适配器:
discard_block_engine shuffle_order_engine independent_bits_engine
5.关于分布器
易知,如果只用generator配上seed只能产生离散的等可能分布,产生的数值在generator的min和max之间,并且结果都是UIntType的值。无法很好的控制产生数值的分布区间和分布概率。如果要实现这种功能就要用到分布器。
作用1:改变生成类型,利用模版参数
作用2:改变值区间,利用实例构造函数参数。或其响应的成员函数设置参数。
作用3:改变概率分布,选用不同的分布器类型
5.1均匀分布:
uniform_int_distribution 整数均匀分布uniform_real_distribution 浮点数均匀分布
5.2伯努利类型分布:(仅有yes/no两种结果,概率一个p,一个1-p)
bernoulli_distribution 伯努利分布binomial_distribution 二项分布geometry_distribution 几何分布negative_biomial_distribution 负二项分布
5.3 Rate-based distributions:
poisson_distribution 泊松分布exponential_distribution 指数分布gamma_distribution 伽马分布 weibull_distribution 威布尔分布extreme_value_distribution 极值分布
5.4正态分布相关:
normal_distribution 正态分布chi_squared_distribution 卡方分布cauchy_distribution 柯西分布fisher_f_distribution 费歇尔F分布student_t_distribution t分布
5.5分段分布相关:
discrete_distribution 离散分布piecewise_constant_distribution 分段常数分布piecewise_linear_distribution 分段线性分布
MyLog:
我的使用方法:
1、加入头文件
#include "random"
2、根据时间设定随机数种子
std::default_random_engine random_engine(time(0)); //随机数种子;std::uniform_int_distribution<int> random_int(0, 1000);//随机数范围在0~1000
3、生成随机数a
int a = random_int(random_engine);
一般的random(),在随机一定次数后会重复
- 【C++11】随机数函数库random
- 【C++11】随机数函数库random
- 【C++11】随机数函数库random
- C#Random 随机数
- C#Random随机数
- C#,Random循环获得随机数的错误
- Objective-C: Get random number 获取随机数
- C#Random产生随机数重复问题
- Random 随机数
- Random 随机数
- 随机数random()
- random随机数
- 随机数Random
- Random随机数
- random随机数
- Random随机数
- C#Random得随机数求均值、方差、正态分布
- objective-c 中随机数的用法 arc4random() 、random()、CCRANDOM_0_1()
- MYSQL经典SQL之时长统计
- rails 代码结构详解
- XMLHttpRequest cannot load http://xxx. Response for preflight has invalid HTTP status code 404
- CSS3的REM设置字体大小:rem
- Laravel获取最近的SQL查询语句Queries
- 【C++11】随机数函数库random
- Android6.0 WMS(十) WMS窗口动画从设置到显示框架
- java经典算法
- Java进阶(四)线程间通信剖析
- Android热补丁方案
- elasticsearch在linux下的安装
- 调用Camera拍照
- Tensorflow读取数据
- Eclipse下设置tomcat,修改Java代码不必重启tomcat