正态分布随机数生成算法

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
s += double(rand() % 1000) / 1000;
return s; }
函数生成的随机数是N个[0,1]间服从均匀分布的随机数的和。这里N 为200。从而理论上产生的随机数应近似服从,其中n为N,即200,为 0.5,为1/12。程序生成了200个随机数,并求出样本均值与样本方差, 也即与的最大似然估计:
cout << i + 1 << '\t' << segments[i]; if (i < 10)
cout << '\t' << fixed << setprecision(2) << (90 + i * 2 - su) / ssb; cout << endl; }
程序的最终运行输出如图2-1所示。
图2-1 最终输出结果 对结果的统计如表2-1所示。由表2-1中可见,今并令,则由于, 故可认为产生的随机数服从正态分布。
表2-1
利用中心极限定理的方法虽然可以得到服从正态分布的随机数样
本,其思想也较为简单,容易想到。但是这种方法每次都要先产生若干 个服从均匀分布的随机数样本并求它们的和,因而算法的时间复杂度 高。
//生成随机数并存储 double sum, store[200], xi, su = 0, sb = 0, ssb = 0; int cnt = 0; sum = 0; for (int i = 0; i != 200; ++i) {
xi = getRand(); sum += xi; store[i] = xi; }
。 接下来再来得出Box Muller方法: 设为一对相互独立的服从正态分布的随机变量。则有概率密度函数 令,其中,则有分布函数: 令 如果服从均匀分布,则的分布函数即为。 最后,可以用代替,令为,其中,,得: 从而,只需要有两个服从均匀分布的随机变量,就能通过公式
来得到一个服从正态分布的随机变量。用Box Muller方法来生成服
1、 方法分析Βιβλιοθήκη Baidu
(1) 利用分布函数的反函数 若要得到分布函数为F(x)的随机变量Y。 可令, 其中u是服从均匀分布的随机变量,有 因而,对于任意的分布函数,只要求出它的反函数,就可以由服从 均匀分布的随机变量实例来生成服从该分布函数的随机变量实例。 现在来看正态分布的分布函数,对于,其分布函数为: 显然,要想求其反函数是相当困难的,同时要想编程实现也很复杂。可 见,用此种方法来生成服从正态分布的随机变量实例并不可取。
int segments[12], m = 2; double x1 = 90, x10 = 108; memset(segments, 0, sizeof(segments));
for (int i = 0; i != 200; ++i) {
if (store[i] <= x1) ++segments[0];
用此函数得到的随机数样本理论上服从。所实现的程序产生了500 个随机变量的样本其他与利用中心极限定理的实现基本相同。程序得到 的最终结果如图2-2所示。
图2-2 对结果的统计如表2-2 所示。
表2-2
由表2-2可见,今并令,则由于,故可认为产生的随机数服从正态 分布。
Box Muller方法的推导过程较为复杂。但得到的结果却是很令人满 意的。只要用两个相互独立的均匀分布就能得到正态分布。而且产生随 机数的时间复杂度比利用中心极限定理的方法要低很多。因而若要产生 服从正态分布的随机数样例,则Box Muller方法是一个很不错的选择。
从正态分布的随机数是十分快捷方便的。我们也将实现这一方法。
2、 实现与分析 (1) 利用中心极限定理方法的实现与分析
利用中心极限定理来生成随机数的函数(C++语言)编写如下:
const int N = 200; double getRand() { double s = 0; for (int i = 0; i != N; ++i)
(2) 利用中心极限定理 第二种方法利用林德伯格—莱维(Lindeberg—Levi)中心极限定理:如 果随机变量序列独立同分布,并且具有有限的数学期望和方差则对一切 有 因此,对于服从均匀分布的随机变量,只要n充分大,随机变量就 服从。我们将实现这一方法。
(3) 使用Box Muller方法 先证明: 令,则 令,则有
//得到样本均匀与样本方差 su = sum / 200; for (int i = 0; i != 200; ++i)
sb += (store[i] - su) * (store[i] - su); sb /= 200; ssb = sqrt(sb);
此次选取 ,它们将实轴分成11个互不相交的区间,从而将样本值分成11组。程 序统计了每组中的样本数量。为方便计算,程序还计算出了:
else if (store[i] > x10) ++segments[10];
else ++segments[int((store[i] - x1) / m + 1)];
} cout << 'i' << '\t' << "ni" << endl; for (int i = 0; i != 11; ++i) {
概率论与数理统计课程设计
题目:正态分布随机数生成算法
要编程得到服从均匀分布的伪随机数是容易的。C语言、Java语言
等都提供了相应的函数。但是要想生成服从正态分布的随机数就没那么 容易了。
得到服从正态分布的随机数的基本思想是先得到服从均匀分布的随 机数,再将服从均匀分布的随机数转变为服从正态分布。接下来就先分 析三个从均匀分布到正态分布转变的方法。然后编程实现其中的两个方 法并对程序实现运作的效果进行统计分析。
(2) Box Muller方法的实现与分析 使用Box Muller方法得到随机数的函数如下:
double getRand() { double u1 = double(rand() % 10000) / 10000, u2 = double(rand() % 10000) / 10000, r; r = 20 + 5 * sqrt(-2.0 * (log(u1) / log(e))) * cos(2 * pi * u2); return r; }
相关文档
最新文档