java产生服从正态分布的随机数
定义
正态分布(Normal distribution),也称“常态分布”,又名高斯分布(Gaussian distribution),
最早由A.棣莫弗在求二项分布的渐近公式中得到。
C.F.高斯在研究测量误差时从另一个角度导出了它。P.S.拉普拉斯和高斯研究了它的性质。
是一个在数学、物理及工程等领域都非常重要的概率分布,在统计学的许多方面有着重大的影响力。
正态曲线呈钟型,两头低,中间高,左右对称因其曲线呈钟形,因此人们又经常称之为钟形曲线。
若随机变量X服从一个数学期望为μ、方差为σ^2的正态分布,记为X~N(μ, σ^2)。
其概率密度函数为正态分布的期望值μ决定了其位置,其标准差σ决定了分布的幅度。当μ = 0,σ = 1时的正态分布是标准正态分布(下图中红色曲线)。
性质
- 密度函数关于平均值对称
- 平均值与它的众数(statistical mode)以及中位数(median)同一数值。
- 函数曲线下68.268949%的面积在平均数左右的一个标准差范围内。
- 95.449974%的面积在平均数左右两个标准差 2σ 的范围内(见下图)。
- 99.730020%的面积在平均数左右三个标准差 3σ 的范围内(见下图)。
- 99.993666%的面积在平均数左右四个标准差 4σ 的范围内(见下图)。
- 函数曲线的拐点(inflection point)为离平均数一个标准差距离的位置。
- 如果X ~ N(μ, σ^2)且a与b是实数,那么 aX+b ~ N(aμ+b, (aσ)^2)
深蓝色区域是距平均值小于一个标准差之内的数值范围。
在正态分布中,此范围所占比率为全部数值之68%,
根据正态分布,两个标准差之内的比率合起来为95%;
三个标准差之内的比率合起来为99%。
称为“68-95-99.7法则”或“经验法则”。
程序实现
常用的实现方法有:
Box-Muller法
以两组独立的随机数U和V,这两组数在(0,1]上均匀分布,用U和V生成两组独立的标准正态分布随机变量X和Y:
X = sqrt(-2ln(U)) cos (2πV)
Y = sqrt(-2ln(U)) sin (2πV)
这个方程的提出是因为二自由度的卡方分布很容易由指数随机变量(方程中的lnU)生成。因而通过随机变量V可以选择一个均匀环绕圆圈的角度,用指数分布选择半径然后变换成(正态分布的)x,y坐标。
因为三角函数计算较慢,我们可以通过上述公式的一个 polar form(极坐标形式)能够简化计算
java实现:
1 | public double normalDsitribution(double miu, double sigmaSquare){ |
JDK实现
JDK中Random类中的nextGaussian()方法,可以产生服从标准正态分布的随机数。即 X~N(0,1);
如果我们想产生自定义的正态分布呢 X~N(μ,b) b=σ^2;
可以用
1 | Math.sqrt(b)*random.nextGaussian() + μ; |
下面是10000测试的分布结果
1 | Random r = new Random(); |
ziggurat算法
一个简单可行的并且容易编程的方法是:求12个在(0,1)上均匀分布的和,然后减6(12的一半)。这种方法可以用在很多应用中。
这12个数的和是Irwin-Hall分布;选择一个方差12。这个随即推导的结果限制在(-6,6)之间,并且密度为12,是用11次多项式估计正态分布。
参考:
https://zh.wikipedia.org/zh-cn/正态分布
https://en.wikipedia.org/wiki/Box–Muller_transform
http://www.elektro-energetika.cz/calculations/no.php
http://www.cnblogs.com/zztt/p/4025207.html
http://echarts.baidu.com/examples/editor.html?c=bar-simple

赞赏是不耍流氓的鼓励