符合正态分布的序列

昨天帮同学解决一个问题,就是如何用C语言去生成符合正态分布的序列。后来在wikipedia找到了答案,本文大部分内容引用wikipedia。

正态分布(Normal Distribution),也叫做高斯分布(Gaussian Distribution),特点是其概率密度函数中间面积大,两边很小。在现实世界的很多问题都遵循正态分布,因此,当使用编程去模拟一些实际问题的时候,也需要用到符合正态分布的序列。

可是,在C语言中,只有一个伪随机函数rand(),它是均匀分布的。如果不是C语言的话,在Java中,Random类有产生符合正态分布序列的方法。C++的Boost库据说也有。可是纯粹的C语言中,怎么办呢?

第一种最容易想到的方法,就是求出正态分布的累积分布函数(Cumulative distribution function),然后求反函数。问题是正态分布的累积分布函数(也就是概率密度函数求积分)无法用简单的表达式表达(回忆一下,我们以前高中学的时候是查表的)。当然,我学过一门数值计算方法的课程,知道可以用复合梯形公式或者复合抛物型公式求积分的值。反函数的话然后只需要二分的方法,把自变量x夹出来即可。

应该说上面的方法也不算难,但是,会有一些误差。维基百科里写着一种很好的方法。首先,要产生a和b两个在(0, 1]范围均匀分布的变量,然后使用下面的公式

那么对于c和d,两个都是符合正态分布的序列,如果只需要一组正态分布,那么只取一个c就可以了。

昨天还验证了,既用rand()产生a,然后再调用rand()产生b,这样轮着用会不会对c产生不良影响。测试的结果表明,c确实符合正态分布,需要注意的是rand()产生的结果要排除0,因为ln0使到程序崩溃。

Advertisements

一个有关“符合正态分布的序列”的想法

  1. 可是我从多种环境都能看到图片,图片是Yupoo的,估计是你的翻墙工具访问不了国内的Yupoo

  2. 一个问题关于第一种:
    第一种方法你的思路是,利用rand随机产生(0,1)的数,累积分布函数再求其反函数得到x,x即产生的正态分布随机数吧?

    但是,对于正态分布来说,若期望为0,即产生0的概率最大,0对应的累积分布函数值应该为0.5,由此推出0.5在产生平均分布的rand中也应概率最大,可rand为平均分布,0.5与其他值应该概率相等。

    所以第一种方法是不是不对?

  3. to3楼,不是,我想你误会了,我说的第一种方法指的是公式法,然后求反函数而已,我没有作进一步的说明,后面的阐述都是第二种方法的内容,不是你说的思路

  4. to lz
    我也觉得你利用累积分布函数求其反函数x,也可能我理解的不对,但觉得有些问题应该
    再交流吧

发表评论

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / 更改 )

Twitter picture

You are commenting using your Twitter account. Log Out / 更改 )

Facebook photo

You are commenting using your Facebook account. Log Out / 更改 )

Google+ photo

You are commenting using your Google+ account. Log Out / 更改 )

Connecting to %s