基于Box-Muller算法的高斯分布随机数产生方法
一,均匀分布的产生思路和方法:
srand((unsigned)time(NULL));
x=rand();
double UNIFORM()
{int x;
double y;
srand((unsigned)time(NULL));
x=rand(); //x就是由基于系统时钟产生的随机数,一个典型的可能的取值可以是:134238
y=(float)(x0); //这个随机数和100求余的结果必然得到一个小与100的整数,然后强制转换成浮点数
y=y/100; //这个数除以100,会得到一个小与1的数。
return y;
}
二,Box-Muller算法:
Box-Muller算法正是利用均匀分布产生高斯分布随机数,算法如下:
上式中的U1和U2就是两个均匀分布随机数,经过这样的一种计算之后就能产生一个Z服从均匀分布的随机数,这看起来太神奇了,不得不佩服这个算法。说明一下,上面的三个式子,前两个取任何一个都可以用作算法,取正弦还是余弦是无所谓的。另外一点,上面的式子仅仅只能产生标准的高斯分布,若要产生给定的均值和方差其实也很简单。
Y=u+(Z*sigma)
好了,基于这个算法,我批量的产生了10000个数,来看看最终的程序代码。
三,完整程序代码:
#include <iostream>
#include <time.h>
#include <iomanip>
#include <math.h>
#include <fstream>
#define PI 3.14159
using namespace std;
void UNIFORM(double *); //UINFORM函数声明
int x = 0; //这里定义x一个全局变量并且初始付值0,这个的功用将会在子函数UNIFORM中得以体现
int main()
{
int i, j;
double A, B, C, E, D, r;
double uni[2];
double *p;
srand((unsigned)time(NULL)); //随机数种子采用系统时钟
ofstream outfile("Gauss.txt", ios::out); //定义文件对象
cout << "输入期望和方差:" << endl;
cin >> E >> D;
for (j = 0; j<10000; j++)
{
UNIFORM(&uni[0]); //调用UNIFORM函数产生2个均匀分布的随机数并存入数组nui[2]
A = sqrt((-2)*log(uni[0]));
B = 2 * PI*uni[1];
C = A*cos(B);
r = E + C*D; //E,D分别是期望和方差
outfile << r << " "; //将数据C输出到被定义的文件中
}
return 0;
}
void UNIFORM(double *p)
{
int i, a;
double f;
for (i = 0; i<2; i++, x = x + 689)
{
a = rand() + x; //加上689是因为系统产生随机数的更换频率远远不及程序调用函数的时间
a = a%1000;
f = (double)a;
f = f / 1000.0;
*p = f;
p++;
}
}
由于本程序执行之后会产生10000个数据,所以没有让他在终端中展示出来,而是利用 outfile<<r<<"
四,Matlab仿真结果:
load F:\VC6.0\MSDev98\Bin\Gauss.txt; %读入数据文件
y=Gauss;
x=-20:0.2:20;
hist(y,x); %绘制直方图