1. 均匀分布
首先,由给定的初值x0,用混合同余法
:
{xi=(a∗xi−1+c)modMyi=xi/M \begin{cases} x_i=(a*x_{i-1}+c) mod M \\ y_i=x_i/M \end{cases} {xi=(a∗xi−1+c)modMyi=xi/M
产生(0, 1)区间上的随机数yi。
其中:a=2045,c=1,M=2^20;
然后,通过变换 zi=a+(b−a)yiz_i=a+(b-a)y_izi=a+(b−a)yi 产生(a,b)区间上的随机数ziz_izi。
#left:下限,right:上限,seed:种子
def uniform(left, right, seed):
a=2045
c=1
M=1048586.0
seed = a * (seed) + c
seed = seed - (seed / M)
yi = (seed) / M
zi = left + (right-left) * yi
return zi
2. 正态分布
可以使用Box Muller
方法,Box Muller方法的推导过程较为复杂,但得到的结果却是很令人满意的。只要用两个相互独立的均匀分布就能得到正态分布用Box-Muller方法,随机抽出两个从均[0,1]匀分布的数字u和v。
z1=−2logu cos2πvz_1=\sqrt{-2logu} \ cos2\pi vz1=−2logu cos2πv
z2=−2logu sinπvz_2=\sqrt{-2logu} \ sin\pi vz2=−2logu sinπv
z1和z2都服从正太分布。也可把两个数相乘一下:
import numpy as np
def boxmullersampling(mu=0, sigma=1, size=1):
u = np.random.uniform(size=size)
v = np.random.uniform(size=size)
z = np.sqrt(-2 * np.log(u)) * np.cos(2 * np.pi * v)
return mu + z * sigma