起因是前几天做A厂的在线编程题,需要用正态分布去生成一个随机数,最后调用了C++自带的正态分布生成库,这时就在想底层是如何实现正态分布的。
由均匀分布生成其他分布的通用性方法
CDF的反函数法/Inverse transform sampling
先用均匀分布生成一个数,把其映射到[0,1]之间
double U = (double)rand() / RAND_MAX;
这样的一个[0,1]分布,怎么将其转换成一个其他分布呢?
这时就用到了概率分布的累积分布函数(CDF- Cumulative distribution function)
找到纵坐标[0,1]对应的横坐标点,就生成了一个满足该概率分布的点。
所以将这个方法形式化一下:
- 用均匀分布生成[0,1]之间的均匀分布产生的数 x
- 找到CDF函数
F(x) 的反函数 F−1(x) 带入反函数中得到的数就是满足该概率分布生成的一个数。
这种方法有一个问题就是,需要算出反函数的解析解,如果没有解析解的话,就不能直接用这种方法了【比如正态分布】
其实仔细一想轮盘赌算法不就是应用的CDF反函数法吗?
Acceptance-Rejection Method/rejection sampling
这个就是应用蒙特卡洛解决一切的思路来了,每次在这个下面这个概率密度坐标里随机生成一个点【随机采样】如果这个点落在了概率密度函数(PDF-probability density function)之下,则采样成功,如果落在了上面则继续采样。
这种方法等于是模拟概率密度函数:它每次生成新的随机数后,通过另一个随机数来保证其被接受概率服从指定的PDF。
正态分布的特定方法
中心极限定理法
中心极限定理:
X1,X2,⋯,Xn 是独立同分布的,分布均值为 μ ,方差为 σ