C++中随机数的生成

摘要:
在简单的应用中,时间可以作为种子。注意:如果未设置种子,则每次生成的随机数序列都是相同的。上述代码生成5个介于1和6之间的随机数,但每次8213918412都更改为以下代码,这会使每次生成的随机数序列不同:1std::default_ random_ enginegenerator;2std::uniform_ int_ distribution<int>dis;3autodice=std::绑定;4for5{6std:。生成值的分布区间和分布概率无法很好地控制。或其响应成员函数。

1.随机数由生成器和分布器结合产生

生成器generator:能够产生离散的等可能分布数值
分布器distributions: 能够把generator产生的均匀分布值映射到其他常见分布,如均匀分布uniform,正态分布normal,二项分布binomial,泊松分布poisson

2.分布器利用运算符()产生随机数,要传入一个generator对象作为参数

1 std::default_random_engine generator;  
2 std::uniform_int_distribution<int> dis(0,100);  
3 for(int i=0;i<5;i++)  
4 {  
5     std::cout<<dis(generator)<<std::endl;  
6 }

 如果嫌每次调用都要传入generator对象麻烦,可以使用std::bind,要包含头文件functional

auto dice = std::bind(distribution,generator)以后就可以直接调用dice()产生复合均匀分布的随机数。
但是多次运行上例会发现每次产生的随机数序列都一样,因为没有设定种子(同cstdlib库中的rand和srand关系)
1 std::default_random_engine generator;  
2 std::uniform_int_distribution<int> dis(0,100);  
3 auto dice= std::bind(dis,generator);  
4 for(int i=0;i<5;i++)  
5 {  
6     std::cout<<dice()<<std::endl;  
7 }  

3.种子

        除了random_device生成器(真随机数生成器或叫f非确定性随机数生成器)以外(linux中有效,windows下其实也是伪随机),所有在库中定义的随机数引擎都是伪随机数生成器,他们都利用了特定的算法实现,这些生成器都需要一个种子。种子可以是一个数值,或者是一个带有generate成员函数的对象。简单的应用中,用time作种子即可。
说明:如果不设定种子,那么产生的随机数序列每次都一样,如上代码,产生5个1到6之间的随机数,但是每次都是82 13 91 84 12
改为如下代码,可以使每次产生的随机数序列不同:
1  std::default_random_engine generator(time(NULL));  
2 std::uniform_int_distribution<int> dis(0,100);  
3 auto dice= std::bind(dis,generator);  
4 for(int i=0;i<5;i++)  
5 {  
6     std::cout<<dice()<<std::endl;  
7 }  

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
如一会介绍的常用生成器:
1 typedef linear_congruential<unsigned long, 16807, 0, 2147483647> minstd_rand0;  
1 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()
mt19937
mt19937_64
4.3滞后Fibonacci法
ranlux24_base
ranlux48_base
利用适配器变种后的滞后Fibonacci法:
ranlux24              ranlux24_base with discard_block_engine
ranlux48              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 分段线性分布

免责声明:文章转载自《C++中随机数的生成》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇转载:国内外高精地图厂商一览flink使用kafka为数据源下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

相关文章

Charles的HTTPS抓包方法及原理分析

原文地址:http://www.jianshu.com/p/870451cb4eb0 背景 作为移动平台的RD,项目开发过程中一项比较重要的甩锅技能——抓包应该大家都比较熟悉了,毕竟有些bug可能是由服务端下发的数据出错导致的。虽然抓包工具很好用,但是如果不做一些设置的话,对于HTTPS协议的请求就无能为力了,比如这样   这对于一些注重安全性的应用...

OpenSSL 介绍和使用

转自:https://www.jianshu.com/p/fb2ae3dc7986 一、SSL 简介 按照我的理解来解释下,为了让网络通信更安全,需要认证和加密,认证是说明你是要找的人,加密是为了让截获中间报文第三者无法得到消息内容。 为此有人设计了SSL,即套接字上的安全层,简单来说就是在TCP之上做一个安全通信层,HTTP on SSL 即是HTT...

C++ 之 伪随机数生成 <random>

C++ 标准库提供了生成随机和伪随机数的类。这些类包括: 随机数生成类:生成均匀分布整数序列的伪随机数生成器,包括随机数引擎、随机数引擎适配器以及预定义随机数生成器。 随机数分布类:将生成器生成的数字序列转换为遵循特定随机变量分布(如均匀分布、正态或泊松分布)的数字序列的对象。 随机数引擎 随机数引擎可以以种子数据为熵源生成伪随机数。 随机种子:初始化...

SSL详解

SSL 1.整体结构 SSL是一个介于HTTP协议与TCP之间的一个可选层,其位置大致如下 SSL:(Secure Socket Layer,安全套接字层),为Netscape所研发,用以保障在Internet上数据传输之安全,利用数据加密(Encryption)技术,可确保数据在网络上之传输过程中不会被截取。当前版本为3.0。它已被广泛地用于Web浏览...

Js 控制随机数概率

(新)控制随机数概率:https://www.cnblogs.com/whnba/p/10565045.html 算法精简了一下   如: 取 1~10 之间的随机数,那么他们的取值范围是: 整数 区间 概率 1 [0,1) 0.1 2 [1,2) 0.1 3 [2,3) 0.1 4 [3,4) 0.1 5 [4,5) 0.1...

Spring Boot配置文件详解:自定义属性、随机数、多环境配置

自定义属性与加载 我们在使用Spring Boot的时候,通常也需要定义一些自己使用的属性,我们可以如下方式直接定义: application-dev.yml 1 com.didispace.blog: 2 3 name: 程序猿DD 4 5 title: Spring Boot教程 6 7 desc: ${com.didispace.blog.na...