【C++11】随机数函数库random

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, 48271, 0, 2147483647> minstd_rand;
typedef linear_congruential<unsigned long, 16807, 0, 2147483647> minstd_rand0;  

可见如果自己实例化模版类很麻烦,需要很强的数序知识,所以有几个常用的几个模版实例化生成器,他们都是需要一个种子参数就可以:

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   分段线性分布

时间: 2024-12-24 00:11:55

【C++11】随机数函数库random的相关文章

Javascript 随机数函数 学习之二:产生服从正态分布随机数

一.为什么需要服从正态分布的随机函数 一般我们经常使用的随机数函数 Math.random() 产生的是服从均匀分布的随机数,能够模拟等概率出现的情况,例如 扔一个骰子,1到6点的概率应该相等,但现实生活中更多的随机现象是符合正态分布的,例如20岁成年人的体重分布等. 假如我们在制作一个游戏,要随机设定许许多多 NPC 的身高,如果还用Math.random(),生成从140 到 220 之间的数字,就会发现每个身高段的人数是一样多的,这是比较无趣的,这样的世界也与我们习惯不同,现实应该是特别高

第6课-函数库设计

1.Linux下的应用程序所需要的外部函数可以由函数可和系统调用提供.2.函数库是处于用户态的,由工作人员编写的函数的集合,而系统调用是由Linux内核实现的.3.函数库分为静态和动态,按照链接方式划分的.动态函数库比静态节约空间.使用静态函数库以后应用程序最终会包含自身和函数库,在内存中运行的时候就会有多个函数可的拷贝,导致在空间上的浪费.而动态函数库则在内存中只有一个拷贝,供多个都会使用到的程序使用.4.Linux使用的函数库一般都是在/lib或者在/usr/lib,以*.so*命名的,是动

C++中的随机数函数(

标签:ul 随机数 c 整数 max 教育  C++中产生随机数种子对于刚開始学习的人一直都非常困惑.大家知道,在C中有专门的srand(N)函数能够轻松实现这一功能,然而在C++中则要复杂一些.以下是笔者学习的一点心得,希望对大家能有所帮助.(这里我们依旧要借助C标准库中的rand()函数) 函数说明: int rand();                                          :返回从[0,MAX)之间的随机整数,这里的MAX与你所定义的数据类型而定:需#inc

Linux C函数库大全

(1)字符测试函数 isalnum(测试字符是否为英文字母或数字) isalpha(测试字符是否为英文字母) isascii(测试字符是否为ASCII码字符) isblank(测试字符是否为空格字符) iscntrl(测试字符是否为ASCII码的控制字符) isdigit(测试字符是否为阿拉伯数字) isgraph(测试字符是否为可打印字符) islower(测试字符是否为小写英文字母) isprint(测试字符是否为可打印字符) isspace(测试字符是否为空格字符) ispunct(测试字

linux C 函数库

第1章字符测试函数 1 isalnum(测试字符是否为英文字母或数字) 2 isalpha(测试字符是否为英文字母) 3 isascii(测试字符是否为ASCII码字符) 4 isblank(测试字符是否为空格字符) 5 iscntrl(测试字符是否为ASCII码的控制字符) 6 isdigit(测试字符是否为阿拉伯数字) 7 isgraph(测试字符是否为可打印字符) 8 islower(测试字符是否为小写英文字母) 9 isprint(测试字符是否为可打印字符) 10 isspace(测试字

标准库random

random - Random variable generators. 随机变量生成器 class Random(_random.Random) -- Random number generator base class used by bound module functions. 以下是所有的random的方法: 1 import random 2 print(random.random()) #生成一个0-1之间的浮点数随机数[0,1] 3 print(random.randint(1,

PHP函数库(other)

PHP函数库(other) Session函数: session_abort — Discard session array changes and finish session session_abort() finishes session without saving data. Thus the original values in session data are kept. 返回值:没有你返回值. session_cache_expire — 返回当前缓存的到期时间 session_

5月11日 函数、练习:阶乘累加求和

一.函数:  一个较大的程序一般应分为若干个程序块,每一个模块用来实现一个特定的功能.所有的高级语言中都有子程序这个概念,用子程序实现模块的功能.在C#语言中,子程序的作用是由一个主函数和若干个函数构成.由主函数调用其它函数,其它函数也可以互相调用.同一个函数可以被一个或多个函数调用任意多次. 在程序设计中,常将一些常用的功能模块编写成函数,放在函数库中供公共选用.要善于利用函数,以减少重复编写程序段的工作量. namespace _5月11日_函数 { class Program { //没有

第一阶段 PHP基础.数学、字符函数库与循环

一位初学php的随堂笔记,记录自己的成长! 一.数学函数库 1.安装:数学函数库是PHPCORE的组成部分 2. (1) floor: 向下取整 (2) ceil: 向上取整 (3)round: 四舍五入 int round(number $var[,int $percision]) (4)pow :求次幂 (5)sqrt:求开平方 (6)max :求最大值 (7)min :求最小值 (8)rand :求整数随机数 (9)mt_rand:求整数更好随机数 二.流程控制语句--循环 1.什么时候用