正态分布也叫高斯分布,normal distribution/gaussian distribution
一般会采用Box-muller提供的方式生成一个服从正态分布的随机数。该思想的代码示例和讲解大家可以百度下,非常多。 基本思想:先得到均匀分布随机数,然后转变为服从正态分布的随机数。
C++11里面提供了新的随机数生成器,通过它,我们可以很方便的实现符合正态分布的随机数。
正态分布包括两个参数,均值和标准差。
我们需要用到norm_distribution和default_random_engine,该函数包含在random库,所以记得**#include**
std::default_random_engine e1(time(0));//default_random_engine e1; e1.seed(32767); std::default_random_engine e2(32767);std::normal_distribution<double> distribution(0,1.0);double rnd = distribution(e1);
第一行创建随机数引擎,其中参数time(0)是随时间而变化的种子seed,当然可以不带参数或者给随便一个数值,这里的思想和srand设置种子是一样的。如果不同的引擎设置相同的种子,那么产生的随机数也就是相同的。如果采用时间种子,就会产生一个新问题,time0返回的时间是秒,如果是一部分反复运行,由于时间间隔不够,所以可能会让设置的种子一样,比如在多次循环中会生成相同的随机数。【不同时刻的秒数是不同的,但同一秒内多次调用此程序所对应的系统秒是相同的。且由于,程序调用时间长短问题,即便获取系统毫秒值也会发生同一毫秒内多次调用的问题。】当然随机数种子容易出现在秒级及秒级以上可用的局面,但是程序的调用可能是小于等于毫秒级别的,这样想要打破上面的局面,就需要用random_device类,来生成 它的对象用来获取真随机数。非常耗费系统资源,所以要谨慎
random_device可以参考 下面这篇文章
random_device
第二行则是创建随机分布对象,double指定了生成的随机数的类型,0,1分别表示了正态分布的期望值和方差两个参数。
一个给定的随机数发生器一直会生成相同的随机数序列。一个函数如果定义了局部的随机数发生器,应该将(引擎和分布对象)定义为 static 的。否则每次调用函数都会生成相同的序列。
staic std::default_random_engine e1(time(0));staic std::normal_distribution<double> distribution(0,1.0);double rnd = distribution(e1);
随机数发生器会生成相同的随机数序列在调试 中很有用。方便我们观察值的变化,对程序进行分析
因此可以使用static关键字使程序运行期间使用同一个随机数引擎,那么所生成的随机数就是不断从随机序列中取出的。
加了static的引擎可以称之为静态随机数引擎
可以注意到,同一个随机数引擎生成的随机序列是可以称为“真随机数”的,因为从原理的角度来看:其在调用时依次取出序列中的下一个数字。所以,也就保证了生成的随机数不相同
当调试完毕,我们通常希望每次运行程序都会生成不同的随机结果,可以通过提供一个 种子 来达到这一目的。
再来介绍下 uniform_int_distribution这个类
使用方式为static uniform_int_distribution u(min,max);即生成的随机数在min ~ max之间,且均为闭区间。
static default_random_engine e;uniform_int_distribution<int> r(1, 10);std::cout << r(e) << " ";