加载中…
个人资料
  • 博客等级:
  • 博客积分:
  • 博客访问:
  • 关注人气:
  • 获赠金笔:0支
  • 赠出金笔:0支
  • 荣誉徽章:
正文 字体大小:

用C产生满足正态分布的随机数

(2013-12-05 18:50:59)
标签:

随机数

正态分布

box-muller

it

正态分布(英:Normal distribution, 德:Normalverteilung)

高斯分布(英:Gaussian distribution, 德:Gaußverteilung)

方法一由均匀分布的随机数来产生

一个简单可行的并且容易编程的方法是:求12个在(0,1)上均匀分布的和,然后减6 (12的一半)。这种方法可以用在很多应用中,这12个数的和是Irwin-Hall分布;选择一个方差12。但此推导的结果限制在(-6,6)之间,并且密度为12

方法二Box-Muller方法

Box-Muller方法是以两组独立的随机数UV,这两组数在(0,1)上均匀分布,用UV生成两组独立的标准正态分布随机变量XY:

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)

0

阅读 收藏 喜欢 打印举报/Report
后一篇:德甲联赛
  

新浪BLOG意见反馈留言板 欢迎批评指正

新浪简介 | About Sina | 广告服务 | 联系我们 | 招聘信息 | 网站律师 | SINA English | 产品答疑

新浪公司 版权所有