1. 均匀分布
首先,由给定的初值x0,用混合同余法
:
{ x i = ( a ∗ x i − 1 + c ) m o d M y i = x i / 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;
然后,通过变换
z
i
=
a
+
(
b
−
a
)
y
i
z_i=a+(b-a)y_i
zi=a+(b−a)yi 产生(a,b)区间上的随机数
z
i
z_i
zi。
#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。
z
1
=
−
2
l
o
g
u
c
o
s
2
π
v
z_1=\sqrt{-2logu} \ cos2\pi v
z1=−2logu cos2πv
z
2
=
−
2
l
o
g
u
s
i
n
π
v
z_2=\sqrt{-2logu} \ sin\pi v
z2=−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