蒙特卡洛(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