算法一产生12个(0,1)皮镇平均分布的随机函数,用大数定理可以模拟出正态分布。
算法二用到了数学中的雅可比变换,直接生成正态分布,但此算法在计算很大规模的数时
会出现溢出错误。
测试程序:茄握巧
#include <math.h>
#include <stdio.h>
#include <conio.h>
#include <stdlib.h>
#include <time.h>
double _random(void)
{
int a
double r
a=rand()%32767
r=(a+0.00)/32767.00
return r
}
double _sta(double mu,double sigma)
{
int i
double r,sum=0.0
if(sigma<=0.0) { printf("Sigma<=0.0 in _sta!") exit(1) }
for(i=1i<=12i++)
sum = sum + _random()
r=(sum-6.00)*sigma+mu
return r
}
double _sta2(double mu,double sigma)
{
double r1,r2
r1=_random()
r2=_random()
return sqrt(-2*log(r1))*cos(2*M_PI*r2)*sigma+mu
}
int main()
{
int i
double mu,sigma
srand( (unsigned)time( NULL ) )
mu=0.0
sigma=1.0
printf("Algorithm 1:\n")
for(i=0i<10i++)
printf("%lf\t",_sta(mu,sigma))
printf("Algorithm 2:\n")
for(i=0i<10i++)
printf("%lf\t",_sta2(mu,sigma))
return 0
}
//由均匀分布的随机数得到正态分布的随机数
#include <math.h>
float gasdev(idum)
int *idum
{
static int iset=0
static float gset
float fac,r,v1,v2
float ran1()//产生均匀分布的随机数,可利用系颤键统函数改写
if (iset == 0) {
do {
v1=2.0*ran1(idum)-1.0
v2=2.0*ran1(idum)-1.0
r=v1*v1+v2*v2
} while (r >= 1.0)
fac=sqrt(-2.0*log(r)/r)
gset=v1*fac
iset=1
return v2*fac
} else {
iset=0
return gset
}
}
原理可找本数值算法方面的书看看。
C语言中计算一个数的N次方可以用宽厅如库函数pow来实现。函数原型:double pow(double x, double y)
功 能:计算x^y的值
返 回 值:计算结伏大果
举例如下:
double a = pow(3.14, 2) // 计算3.14的平方
注:使用pow函数时,需慎启要将头文件#include<math.h>包含进源文件中。
double gaussian(double u) //用Box_Muller算法产生高斯分布的随机数{
double r,t,z,x
double s1,s2
s1=(1.0+rand())/册吵(RAND_MAX+1.0)
s2=(1.0+rand())/(RAND_MAX+1.0)
r=sqrt(-2*log(s2)/log(e))
t=2*pi*s1
z=r*cos(t)
x=u+z*N
return x
}
以前写的一个函数春搏,u是均值,N是方扒姿祥差
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)