【数学】均匀分布生成其他分布的方法

来源:互联网 发布:wiley数据库使用方法 编辑:程序博客网 时间:2024/05/16 01:47

起因是前几天做A厂的在线编程题,需要用正态分布去生成一个随机数,最后调用了C++自带的正态分布生成库,这时就在想底层是如何实现正态分布的。

由均匀分布生成其他分布的通用性方法

CDF的反函数法/Inverse transform sampling

先用均匀分布生成一个数,把其映射到[0,1]之间

double U = (double)rand() / RAND_MAX;

这样的一个[0,1]分布,怎么将其转换成一个其他分布呢?
这时就用到了概率分布的累积分布函数(CDF- Cumulative distribution function)
这里写图片描述
找到纵坐标[0,1]对应的横坐标点,就生成了一个满足该概率分布的点。
所以将这个方法形式化一下:

  1. 用均匀分布生成[0,1]之间的均匀分布产生的数x
  2. 找到CDF函数F(x)的反函数F1(x)带入反函数中得到的数就是满足该概率分布生成的一个数。

这种方法有一个问题就是,需要算出反函数的解析解,如果没有解析解的话,就不能直接用这种方法了【比如正态分布】
其实仔细一想轮盘赌算法不就是应用的CDF反函数法吗?

Acceptance-Rejection Method/rejection sampling

这个就是应用蒙特卡洛解决一切的思路来了,每次在这个下面这个概率密度坐标里随机生成一个点【随机采样】如果这个点落在了概率密度函数(PDF-probability density function)之下,则采样成功,如果落在了上面则继续采样。

这里写图片描述
这种方法等于是模拟概率密度函数:它每次生成新的随机数后,通过另一个随机数来保证其被接受概率服从指定的PDF。

正态分布的特定方法

中心极限定理法

中心极限定理
X1,X2,,Xn是独立同分布的,分布均值为μ,方差为σ2

Zn=X1+X2++Xnnμσn

nZnN(0,1)
一定要注意分母σn,这个分布是Var(X1+X2++Xn)
因为随机变量和的方差D(x+y)=D(x)+D(y)+2Cov(x,y)而上面的变量是独立同分布的,所以
D(X1+X2++Xn)=D(X1)+D(X2)++D(Xn)=nσ2

ZnX1+X2++Xn分布的标准化
用这种方法生成尽可能多的均匀分布,然后求和归一化之后就是标准正态分布生成的x,然后y=xσ+μ就得到了所需的正态分布【这里的σμ跟上面的不一样,这里是所需的正态分布的。

Box-Muller

这个其实方法本质上也是用CDF的反函数,只不过在x,y坐标系下不能直接求解正态分布的CDF,将其转移到极坐标下求解。有些C++的编译器调用的是这种生成正态分布的方法。具体推导见如下:
这里写图片描述
这个地方用到的数学知识太多,接下来再补一篇单独列点其中的数学知识。

ziggurat方法

因为Box-Muller方法需要进行log和cos的运算,所以效率不是太高。而rejection sampling又会造成不少的浪费,所以就有了采样拒绝率不那么高的方法。
这个方法是《Numerical Computing with MATLAB》提到的方法
这个方法详见[4]中所说

参考资料

  1. 如何产生正态分布的随机数?
  2. 生成特定分布随机数的方法
  3. 均匀分布生成标准正态分布 python
  4. 漫谈正态分布的生成
0 0
原创粉丝点击