欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

利用Box-Muller变换生成正态分布的随机数

程序员文章站 2024-03-25 21:36:16
...

       前言

       之前的文章中笔者有提到利用独立同分布的中心极限定理生成正态分布的随机数,对随机数的分布特性要求越高,利用独立同分布的中心极限定理生成正态分布的随机数的算法时间复杂度也越高,如果需要大量的正态分布随机数“利用独立同分布的中心极限定理生成正态分布的随机数”的做法是不可取的。本文将为大家带来时间复杂度较低的算法——利用Box-Muller变换生成正态分布的随机数。

      Box-Muller变换

      设利用Box-Muller变换生成正态分布的随机数是在[0,1)上遵从均匀分布的随机数(生成[0,1)上遵从均匀分布的随机数通常使用的是梅森旋转算法),令

利用Box-Muller变换生成正态分布的随机数

利用Box-Muller变换生成正态分布的随机数

利用Box-Muller变换生成正态分布的随机数必然遵守二元正态分布,即利用两个独立的遵从均匀分布的随机数得到两个独立的正态分布的随机数

定理证明过程

      设

利用Box-Muller变换生成正态分布的随机数

利用Box-Muller变换生成正态分布的随机数

     令利用Box-Muller变换生成正态分布的随机数

       利用Box-Muller变换生成正态分布的随机数

由概率密度函数的变换公式可得

利用Box-Muller变换生成正态分布的随机数

(雅可比式利用Box-Muller变换生成正态分布的随机数的定义可以参见数学分析教材)

因为利用Box-Muller变换生成正态分布的随机数是在[0,1)上遵从均匀分布的随机数,故利用Box-Muller变换生成正态分布的随机数

通过计算雅可比式的值,可得

利用Box-Muller变换生成正态分布的随机数

联立(1)(2)可得

利用Box-Muller变换生成正态分布的随机数

利用Box-Muller变换生成正态分布的随机数

此式恰为二元标准正态分布的概率密度函数

证毕

C++实现过程

//作者cclplus 如有疑问可请联系作者邮箱aaa@qq.com,作者会在后续内容中进行解释
#include <iostream>
#include <cmath>
#include <cstdlib>

using namespace std;
const double pi = 3.1415926897932384;
int main() {
	ios::sync_with_stdio(false);
	double x1, x2,y1,y2;
	int seed;//手动输入种子
	cout << "手动输入种子(任意给出一个整数)" << endl;
	cin >> seed;
	srand(seed);
	x1 = rand()% RAND_MAX /(double) RAND_MAX;
	x2= rand() % RAND_MAX / (double)RAND_MAX;
	cout << "产生的均匀分布的随机数种子为" << endl;
	cout << x1 <<" "<< x2 << endl;
	y1 = sqrt(-2 * log(x1))*cos(2 * pi*x2);
	y2 = sqrt(-2 * log(x1))*sin(2 * pi*x2);
	cout << "输出的正态分布的随机数为" << endl;
	cout << y1 << " " << y2 << endl;
	return 0;
}

利用matlab设计验证性实验

生成一百万个正态分布的函数,并对结果进行验证

%作者cclplus 有疑问请联系aaa@qq.com
clc
clear all
close all
n=1000000;
x1=rand(n,1);
x2=rand(n,1);
y1=sqrt(-2.*log(1.*x1)).*cos(2*pi.*x2);%生成正态分布函数
figure;
normplot(y1);%样本数据在图中用“+”显示;如果数据来自正态分布,则图形显示为直线,而其它分布可能在图中产生弯曲。

 

测试结果

利用Box-Muller变换生成正态分布的随机数

如果想要生成其它类型的正态分布随机数,可以参考我之前写的文章,利用独立同分布的中心极限定理生成正态分布的随机数