分别用三个不同的算法写了三个正态分布的函数,然后用一个函数中的一个对于Math.random()取整然后随机选取函数的方法来选择以上的随机数函数,这样可以另生成的正态分布随机数更随机! 三个正态分布的函数(其中两个参数分别为均值和方差): public double normalRandom1(double a, double b) { double temp = 12; double x = 0; for (int i = 0; i < temp; i++) x = x + (Math.random()); x = (x - temp / 2) / (Math.sqrt(temp / 12)); x = a + x * Math.sqrt(b); return x; }double normalRandom2(double a, double b) { double pi = 3.1415926535; double r1 = Math.random(); Math.random(); Math.random(); Math.random(); Math.random(); Math.random(); Math.random(); Math.random(); double r2 = Math.random(); double u = Math.sqrt((-2) * Math.log(r1)) * Math.cos(2 * pi * r2); double z = a + u * Math.sqrt(b); return (z); }double normalRandom3(double a, double b) { double f = 0; double c0 = 2.515517, c1 = 0.802853, c2 = 0.010328; double d1 = 1.432788, d2 = 0.189269, d3 = 0.001308; double w; double r = Math.random(); if (r <= 0.5) w = r; else w = 1 - r; if ((r - 0.5) > 0) f = 1; else if ((r - 0.5) < 0) f = -1; double y = Math.sqrt((-2) * Math.log(w)); double x = f * (y - (c0 + c1 * y + c2 * y * y) / (1 + d1 * y + d2 * y * y + d3 * y * y * y)); double z = a + x * Math.sqrt(b); return (z); } 然后判断用哪个正态分布随机数函数的方法如下: double normalRandom(double a, double b) { double r = Math.random() * 9; switch ((int) r / 3) { case 0: return normalRandom1(a, b); case 1: return normalRandom2(a, b); case 2: return normalRandom3(a, b); } return 0.0; }
nextGaussian不可重寫,所以用起來不理想。
根据独立同分布的中心极限定理,有:
这里,其实只要取n=12(这里,亦即生成12个0-1上的随机数序列)就会有比较好的效果。 经验证,用该种方法生成生的随机数序列同样能比较好的符合正态分布特性。 由于生成的都是标准正态分布,所以,当需要生成N(a,b)的正态分布随机量时,根据正态分布的线性变换特性,只要用x=b*x0+a即可。(其中,x0表示生成的符合N(0,1)分布的正态随机变量。) 自己编的代码如下: public double Norm_rand(double miu, double sigma2){
double N = 12;
double x=0,temp=N;
do{
x=0;
for(int i=0;i <N;i++)
x=x+(Math.random());
x=(x-temp/2)/(Math.sqrt(temp/12));
x=miu+x*Math.sqrt(sigma2);
}while(x <=0); //在此我把小于0的数排除掉了
return x;
} 参考
http://topic.csdn.net/u/20080827/11/35c2149b-ae1d-4f89-ab16-e9f153f771b8.html
三个正态分布的函数(其中两个参数分别为均值和方差):
public double normalRandom1(double a, double b) {
double temp = 12;
double x = 0;
for (int i = 0; i < temp; i++)
x = x + (Math.random());
x = (x - temp / 2) / (Math.sqrt(temp / 12));
x = a + x * Math.sqrt(b);
return x;
}double normalRandom2(double a, double b) {
double pi = 3.1415926535;
double r1 = Math.random();
Math.random();
Math.random();
Math.random();
Math.random();
Math.random();
Math.random();
Math.random();
double r2 = Math.random();
double u = Math.sqrt((-2) * Math.log(r1)) * Math.cos(2 * pi * r2);
double z = a + u * Math.sqrt(b);
return (z);
}double normalRandom3(double a, double b) {
double f = 0;
double c0 = 2.515517, c1 = 0.802853, c2 = 0.010328;
double d1 = 1.432788, d2 = 0.189269, d3 = 0.001308;
double w;
double r = Math.random();
if (r <= 0.5) w = r;
else w = 1 - r;
if ((r - 0.5) > 0) f = 1;
else if ((r - 0.5) < 0) f = -1;
double y = Math.sqrt((-2) * Math.log(w));
double x = f * (y - (c0 + c1 * y + c2 * y * y) / (1 + d1 * y + d2 * y * y + d3 * y * y * y));
double z = a + x * Math.sqrt(b);
return (z);
}
然后判断用哪个正态分布随机数函数的方法如下:
double normalRandom(double a, double b) {
double r = Math.random() * 9;
switch ((int) r / 3) {
case 0:
return normalRandom1(a, b);
case 1:
return normalRandom2(a, b);
case 2:
return normalRandom3(a, b);
}
return 0.0;
}
-_-!