蒙特卡洛算法


蒙特卡洛(Monte Carlo)方法,又稱隨機抽樣或統計試驗方法,是以概率和統計理論方法為基礎的一種計算方法。該方法使用隨機數(或更常見的偽隨機數)來解決很多計算問題,將所求解的問題同一定的概率模型相聯系,用電子計算機實現模擬或抽樣,以獲得問題的近似解。

基本原理

蒙特卡羅方法通過抓住事物運動的幾何數量和幾何特征,利用數學方法來加以模擬,即進行一種數字模擬實驗。它以一個概率模型為基礎,按照這個模型所描繪的過程,通過模擬實驗的結果,作為問題的近似解。蒙特卡羅解題可歸結為三個主要步驟。

  • 構造或描述概率過程
  • 實現從已知概率分布抽樣
  • 建立各種評估量

借助計算機技術,蒙特卡羅模擬實現了兩大優點:

簡單,省卻了繁雜的數學報導和演算過程,使得一般人能夠理解和掌握

快速,簡單和快速

蒙特卡羅模擬的特點:隨機采樣上計算得到近似結果,隨着采樣的增加,得到的結果是正確的結果的概率逐漸增大。

 

 

1.π的計算

 

n = 10000
r = 1.0
a,b = 0.0,0.0
xmin,xmax = a-r,a+r
ymin,ymax = b-r,b+r
x = np.random.uniform(xmin,xmax,n)   #均勻生成介於xmin和xmax的n個值
y = np.random.uniform(ymin,ymax,n)

fig = plt.figure(figsize = (8,8))
ax = fig.add_subplot(111)
plt.plot(x,y,'ro',markersize = 1) #散點圖,也即plt.scatter(x,y,s=1)
plt.axis('equal')

from matplotlib.patches import Circle
circle = Circle(xy=(a,b),radius=r,alpha = 0.5,color = 'gray')  #xy表示圓心位置,radius表示半徑
ax.add_patch(circle)

d = np.sqrt((x-a)**2+(y-b)**2)  #求點到圓心的距離
m = len(d[d < r])  #落在圓內的點的個數

#圓的面積/正方形面積=π*(r**2)/(2r)**2 = π/4    =    圓內的點的個數/總個數 = m/n
π = 4*m/n
print(π)   # 3.1388

 

2.積分的計算

n = 10000
xmin,xmax = 0,1.0  #矩形x軸邊界
ymin,ymax = 0,1.0  #矩形y軸邊界
x = np.random.uniform(xmin,xmax,n)  
y = np.random.uniform(ymin,ymax,n)  

fig = plt.figure(figsize = (8,8))
ax = fig.add_subplot(111)
plt.scatter(x,y,s=0.5)   #在矩形內隨機投點
plt.xlim([0,1])
plt.ylim([0,1])

xi = np.linspace(0,1,100)
yi = xi**2
plt.plot(xi,yi,linestyle='--',color = 'red')  #繪制y = x**2曲線
plt.fill_between(xi,yi,0,color='gray',alpha=0.5)  #填充y<x**2部分

m = len(d[y<x**2])  #求落在陰影部分的點的個數
integral = m/n  #陰影部分點的個數/總個數
print(integral)  #0.3326

 

3.排隊上廁所問題

# 1.兩場電影結束時間相隔較長,互不影響;
# 2.每場電影結束之后會有20個人想上廁所;
# 3.這20個人會在0到10分鍾之內全部到達廁所);
# 4.每個人上廁所時間在1-3分鍾之間
# 首先模擬最簡單的情況,也就是廁所只有一個位置,不考慮兩人共用的情況則每人必須等上一人出恭完畢方可進行。
# 分析:對於每個人都有幾個參數:到達時間 / 等待時間 / 開始上廁所時間 / 上廁所時間 / 結束時間
arrivingtime = np.random.uniform(0,10,20)  #到達時間
arrivingtime.sort()
workingtime = np.random.uniform(0,3,20)    #上廁所時間
startingtime = [0 for i in range(20)]     #開始時間
waitingtime = [0 for i in range(20)]      #等待時間
finishingtime = [0 for i in range(20)]    #完成時間
emptytime = [0 for i in range(20)]        #廁所空閑時間

startingtime[0] = arrivingtime[0]   #第一個人開始時間等於到達時間
finishingtime[0] = startingtime[0] + workingtime[0]  #第一個人結束時間等於開始時間+上廁所時間
waitingtime[0] = startingtime[0] - arrivingtime[0]

print(arrivingtime[0],waitingtime[0],startingtime[0],workingtime[0],finishingtime[0])
print('-------------------------------------')
print('        到達時間 等待時間 開始時間 消耗時間 結束時間  廁所空閑時間')

for i in range(len(arrivingtime)-1):
    if arrivingtime[i+1]<=finishingtime[i]:    #如果某個人到達,上一個人尚未結束,則這個人的開始時間為上一個人的結束時間
        emptytime[i] =  0
        startingtime[i+1] = finishingtime[i]    
    else:
        emptytime[i] = arrivingtime[i+1] - finishingtime[i]
        startingtime[i+1] = arrivingtime[i+1]  #如果某個人到達,上一個人已結束,則這個人的開始時間即為他的到達時間
    waitingtime[i+1] = startingtime[i+1] - arrivingtime[i+1]
    finishingtime[i+1] = startingtime[i+1]+ workingtime[i+1]
        
for i in range(len(arrivingtime)) :
    print('第 %d個人:%.5f, %.5f, %.5f, %.5f, %.5f, %.5f'%(i,arrivingtime[i],waitingtime[i],startingtime[i],workingtime[i],finishingtime[i],emptytime[i]))
 
print('平均等待時間為:',np.mean(waitingtime))

fig = plt.figure(figsize = (6,4))
plt.plot(waitingtime, '-go')
plt.grid(True,linestyle='--', color = 'gray',linewidth = '0.8')
plt.title('蒙特卡羅模擬 - 排隊上廁所問題')
0.2736595351122484 0.0 0.2736595351122484 0.38688603398898835 0.6605455691012367
-------------------------------------
        到達時間 等待時間 開始時間 消耗時間 結束時間  廁所空閑時間
第 0個人:0.27366, 0.00000, 0.27366, 0.38689, 0.66055, 0.00000
第 1個人:0.56116, 0.09938, 0.66055, 0.43453, 1.09507, 0.35845
第 2個人:1.45352, 0.00000, 1.45352, 0.21734, 1.67086, 0.56067
第 3個人:2.23153, 0.00000, 2.23153, 0.69145, 2.92298, 0.00000
第 4個人:2.44763, 0.47535, 2.92298, 1.53950, 4.46249, 0.00000
第 5個人:2.83300, 1.62948, 4.46249, 2.88175, 7.34424, 0.00000
第 6個人:4.33856, 3.00568, 7.34424, 1.86335, 9.20758, 0.00000
第 7個人:4.34006, 4.86752, 9.20758, 2.33044, 11.53803, 0.00000
第 8個人:4.59969, 6.93834, 11.53803, 0.75576, 12.29379, 0.00000
第 9個人:4.61749, 7.67631, 12.29379, 0.59378, 12.88758, 0.00000
第 10個人:4.74960, 8.13797, 12.88758, 2.01128, 14.89885, 0.00000
第 11個人:4.89969, 9.99916, 14.89885, 0.67834, 15.57720, 0.00000
第 12個人:5.07639, 10.50081, 15.57720, 1.03112, 16.60832, 0.00000
第 13個人:5.93106, 10.67725, 16.60832, 2.04646, 18.65478, 0.00000
第 14個人:7.03743, 11.61735, 18.65478, 2.48112, 21.13590, 0.00000
第 15個人:7.04236, 14.09354, 21.13590, 2.99854, 24.13444, 0.00000
第 16個人:8.39554, 15.73890, 24.13444, 2.72812, 26.86256, 0.00000
第 17個人:8.62632, 18.23625, 26.86256, 0.46716, 27.32973, 0.00000
第 18個人:8.70150, 18.62823, 27.32973, 2.67838, 30.00811, 0.00000
第 19個人:8.80044, 21.20767, 30.00811, 0.67289, 30.68100, 0.00000
平均等待時間為: 8.176459882353335
輸出結果

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM