正态分布(英:Normal
distribution,
德:Normalverteilung)
高斯分布(英:Gaussian
distribution,
德:Gaußverteilung)
方法一:由均匀分布的随机数来产生
一个简单可行的并且容易编程的方法是:求12个在(0,1)上均匀分布的和,然后减6
(12的一半)。这种方法可以用在很多应用中,这12个数的和是Irwin-Hall分布;选择一个方差12。但此推导的结果限制在(-6,6)之间,并且密度为12。
方法二:Box-Muller方法
Box-Muller方法是以两组独立的随机数U和V,这两组数在(0,1)上均匀分布,用U和V生成两组独立的标准正态分布随机变量X和Y:
X=-2
lnU cos(2πV)
Y=-2
lnV sin(2πV)
方法三:由正态曲线直观效果
http://s9/mw690/001o34XFgy6EL4lLXGE58&690
要让产生的随机数服从这种分布,可以在上图产生均匀分布的随机点,然后只保留概率密度曲线下方的随机点,它们的横坐标就服从了正态分布,即我们要产生的随机数。
测试代码
#include<stdio.h>
#include<stdlib.h>
#include<math.h>
#include<time.h>
#define
PI 3.141593
#define
NUM 1000
//return a random
number (double) with a Uniform Distribution, the value is between
min and max
doublerandom_uniform_distribution(double
min, double max)
{
return
min+(max-min)*rand()/(RAND_MAX+1.0);
//RAND_MAX is 0x7FFF
//According to the time-based seed which
was initialised by srand(), a random number is
created.
//If no seed was initialised by srand(),
rand() would use the seed initialised by srand(1) automatically and
a pseudo-random number would be created.
//Do NOT initialise seed within this
sub-function, because everytime when this function is called, the
seed would be initialised newly. CPU runs repaidly, there may be no
time-difference among several successive calling for the function,
and the seeds initialised are more likely the same, so the
phenomenon that the random numbers obtained are all the same may
occur.
}
//return a random
number (double) with a Normal Distribution, base on Irwin-Hall
Algorithm
doublerandom_normal_distribution_IrwinHall()
{
int i=0;
double sum=0.0;
for(i=0;i<12;i++)
sum+=random_uniform_distribution(0.0,1.0);
return sum-6.0;
}
//return a random
number (double) with a Normal Distribution, base on Box-Muller
Algorithm
doublerandom_normal_distribution_BoxMuller(double
mean, double std)
{
double u_1;
double u_2;
double R;
double theta;
u_1=random_uniform_distribution(0,1);
u_2=random_uniform_distribution(0,1);
R=sqrt((-2)*log(u_2));
theta=2*PI*u_1;
return
mean+(R*sin(theta))*std;
};
//Probability Density
Function of normal distribution
doublepdf_normal_distribution(double
x, double mean,double std)
{
if (0==std)
std=0.000000001;
return
exp(-(x-mean)*(x-mean)/(2*(std)*(std)))/(sqrt(2*PI)*std);
}
//return a random
number (double) with a Normal Distribution, base on probability
density function
doublerandom_normal_distribution_pdf(double
mean, double std, double min ,double max)
{
double x,y,dScope;
do{
x=random_uniform_distribution(min,max);
y=pdf_normal_distribution(x,mean,std);
dScope=random_uniform_distribution(0.0,pdf_normal_distribution(mean,mean,std));
}
while(dScope>y);
return x;
}
void
main()
{
int i;
FILE *fp=fopen("Random numbers with
normal distribution.txt","w");
time_t t;
//return the seconds since 00:00:00 on
Jan 1st 1970
srand(time(&t)); //initialising time-based seed
for(i=0;i
{
printf("%lf\n",random_uniform_distribution(0,10));
}
fprintf(fp,"The 1000 random numbers
based on Irwin-Hall Algorithm:\n");
fprintf(fp,"=[");
for(i=0;i
fprintf(fp,"%lf,
",random_normal_distribution_IrwinHall());
fprintf(fp,"%lf];\n",random_normal_distribution_IrwinHall());
fprintf(fp,"\nThe 1000 random numbers
based on Box-Muller Algorithm:\n");
fprintf(fp,"=[");
for(i=0;i
fprintf(fp,"%lf,
",random_normal_distribution_BoxMuller(0.0,1.0));
fprintf(fp,"%lf];\n",random_normal_distribution_BoxMuller(0.0,1.0));
fprintf(fp,"\nThe 1000 random numbers
based on probability density function:\n");
fprintf(fp,"=[");
for(i=0;i
fprintf(fp,"%lf,
",random_normal_distribution_pdf(0.0,1.0,-10.0,10.0));
fprintf(fp,"%lf];\n",random_normal_distribution_pdf(0.0,1.0,-10.0,10.0));
}
补充,C#下产生均匀分布的随机数:
Random rnd =
new Random();
int n = rnd.Next(a,b);
// [a,b)
double
m =
rnd.NextDouble();
// [0.0,1.0)
加载中,请稍候......