c++构建正态分布的随机数

来源:互联网 发布:上海师范大学网络课程 编辑:程序博客网 时间:2024/06/02 07:15

最近编程的时候遇到一个问题,需要用c++来产生一个满足正态分布的的随机数,用c++产生一个均匀分布的随机数很容易,但是满足正态分布还是有点懵逼的。然后就在网上搜一些资料,发现有三种方法可以产生正态分布的随机数。但是看别人从理论上的推导,感觉还是没有说清楚,我想写写关于我自己对于这三种方法的理解!!

方法一: 利用分布函数的反函数来求取

在讲这个方法前,我要先证明一个定理:就是任何分布函数的概率都服从随机分布!!
假设y=f(x),f(x)是x的分布函数,假设f(x)是连续函数,而且单调递增,则存在反函数x=f(-1)(y),有:
这里我们对于反函数,就考虑0<y<1的时候,简单一点分析:
由上式可知,,说明y是一个均匀分布函数。
之后证明一下为什么可以分布函数的反函数可以求取正态分布的随机数??
假设x=f(-1)(y),由上面可知,y是一个均匀分布的函数,x是它的反函数,我们要求的就是x的值。
上面式子可能你会有点看不懂,你可以从另外一个角度来理解,y=f(x),f(x)是分布函数的值,则有x=f(-1)(y),x是服从正态分布的,所以可以求分布函数的反函数来得到x。
但是很不幸的是,一般正态分布的反函数都很难求,但是并不是这种思想没有用,下面介绍的box-muller方法就是基于反函数方法的改进。

方法2:利用中心极限定理

首先介绍一下中心极限定理的基本原理,设X1,X2,......Xn,是独立同分布的随机变量列,且有均存在,这随机变量满足:

可以看出,当数据量很大时,随机变量近似的服从正态分布,由此,随机变量近似的满足分布
通过中心极限定理可以很快的写出相应的代码,很简单,但是运算量会很大,占用很大的时间复杂度。

方法3 box-muller方法

这个方法是反函数的方法的变形,需要推导了,比较麻烦,但是运算量小,是我们常用的产生正态分布随机数的方法。
首先我们先来求服从正态分布的随机数,该正态分布的密度函数为
设(X,Y)是一对相对独立服从上述正态分布的随机数,则其概率密度函数为:
我们设,则对于r的分布函数有
下面我们来对其进行化简:
则对于r的分布函数求反函数,可得:
可以令(1-Z)为均匀分布的随机数,这里因为Z为r的分布密度,所以Z为均匀分布,1-Z也为均匀分布。均匀分布的反函数即满足该分布的随机数。
U1,U2都满足在(0,1)区间内的均匀分布。
通过上面的公式就可以得到满足的随机数,我们如果要求得到满足的随机数,只需要在
向左或向右平移u个单位即可。
这样,通过上述的公式就可以得到满足的随机数了。
下面贴上用box-muller方法产生随机数的c代码:
#include#include  #include