logo头像
Snippet 博客主题

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
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
public double normalDsitribution(double miu, double sigmaSquare){
return miu+(randomNormalDistribution()*sigmaSquare);
}

public double randomNormalDistribution(){
double u, v, w, c;
do {
//获得两个(-1,1)的独立随机变量
u = Math.random() * 2 - 1.0;
v = Math.random() * 2 - 1.0;
w = u * u + v * v;
} while (w == 0.0 || w >= 1.0);
//这里就是 Box-Muller转换
c = Math.sqrt((-2 * Math.log(w)) / w);
//返回2个标准正态分布的随机数,封装进一个数组返回
//当然,因为这个函数运行较快,也可以扔掉一个
//return [u*c,v*c];
return u * c;
}

JDK实现

JDK中Random类中的nextGaussian()方法,可以产生服从标准正态分布的随机数。即 X~N(0,1);

如果我们想产生自定义的正态分布呢 X~N(μ,b) b=σ^2;
可以用

1
Math.sqrt(b)*random.nextGaussian() + μ;

下面是10000测试的分布结果

1
2
3
4
Random r = new Random();
for (int i = 0; i < 10000; i++) {
r.nextGaussian() * Math.sqrt(10) + 53;
}

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

微信打赏

赞赏是不耍流氓的鼓励