S.P.隨機模擬(Python實現)
隨機模擬(Stochastic Simulation)
隨機模擬又稱Monte-Carlo方法,是一種基於“隨機數”的計算方法。該方法在上個世紀,是十大算法之一。
隨機模擬我們可以理解爲:讓計算機去扔骰子,最基本的在於隨機數的生成。
逆變換法
逆變換法方法簡單,算法效率高,但存在侷限:
- 程序運行可能出錯,有的分佈函數的反函數在0或1初的值是無窮大
- 分佈函數必須嚴格單調遞增,否則反函數不存在,需要用廣義反函數
- 如果反函數的解析表達式無法寫出,可能導致計算速度過慢,甚至無法計算
接受-拒絕法(acceptance-rejection)
接受-拒絕法的思想可以形象地比喻爲製作沙雕,經歷由粗到細的雕琢過程。
其缺陷在於效率較低,由於算法要隨機地拒絕許多建議的隨機數,根據算法效率,我們估計迭代N次後最終會得到隨機數的數量大約是N/M。選擇合適的建議概率密度函數g(x)是算法的關鍵。
在完全使Mg(x)罩住f(x)的前提下,g(x)選擇的原則是:
- M儘可能小
- 建議概率密度函數g(x)要容易被抽樣
- 在滿足前面兩個要求的基礎上,Mg(x)儘可能與f(x)形似
隨機模擬計算圓周率π
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
% matplotlib inline
r=1.0
a,b=(0.0,0.0)
xmin,xmax=a-r,a+r
ymin,ymax=b-r,b+r
n=10000
x=np.random.uniform(xmin,xmax,n)
y=np.random.uniform(ymin,ymax,n)
fig=plt.figure(figsize=(6,6))
axes=fig.add_subplot(1,1,1)
plt.plot(x,y,'ro',markersize=1)
plt.axis('equal')
d=np.sqrt((x-a)**2 + (y-b)**2)
res=sum(np.where(d<r,1,0))
print('落在圓內的點有%i個' % res)
pi = 4*res/n
print("π的近似值爲:",pi)
from matplotlib.patches import Circle
circle=Circle(xy=(a,b),radius=r,alpha=0.5,color='r')
axes.add_patch(circle)
plt.grid(True,linestyle='--',linewidth='0.5')
落在圓內的點有7841個
π的近似值爲: 3.1364