數學模型:4. 隨機算法| 蒙特卡羅算法


 隨機算法

 

1. 蒙特卡羅模擬

 

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

① π的計算
② 計算積分 y = x**2
③ 排隊上廁所問題

 

import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
% matplotlib inline
# π的計算

from matplotlib.patches import Circle

n = 10000
# 投點次數

r = 1.0           # 半徑
a, b = (0.0, 0.0)   # 圓心
# 圓的信息

x_min, x_max = a-r, a+r
y_min, y_max = b-r, b+r
# 正方形區域邊界

x = np.random.uniform(x_min, x_max, n) # 均勻分布
y = np.random.uniform(y_min, y_max, n)
# 在正方形區域內隨機投點
# numpy.random.uniform(low,high,size) → 從一個均勻分布[low,high)中隨機采樣,均勻分布

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))
# 計算點到圓心的距離
# 統計落在圓內的點的數目

pi = 4 * res / n
print(pi)

circle = Circle(xy = (a,b),radius = r, alpha = 0.5 ,color = 'gray')
axes.add_patch(circle)
plt.grid(True, linestyle = "--",linewidth = "0.8")
plt.show()
# 繪制圓形

 

 

# 計算積分 y = x**2 

n = 10000
# 投點次數

x_min, x_max = 0.0, 1.0
y_min, y_max = 0.0, 1.0   
# 矩形區域邊界

x = np.random.uniform(x_min, x_max, n) # 均勻分布
y = np.random.uniform(y_min, y_max, n)
# 在矩形區域內隨機投點

def f(x):
    return x**2
# 創建函數 y = x**2

res = sum(np.where(y < f(x), 1, 0))
# 統計 落在函數 y=x^2圖像下方的點的數目

integral = res / n
print('integral: ', integral)
# 計算 定積分的近似值

fig = plt.figure(figsize = (6,6)) 
axes = fig.add_subplot(111) 
axes.plot(x, y,'ro',markersize = 1)
plt.axis('equal') 
# 繪制散點圖

xi = np.linspace(0,1,100)
yi = xi ** 2
plt.plot(xi,yi,'--k')
plt.fill_between(xi, yi, 0, color ='gray',alpha=0.5,label='area')  
plt.grid()
# 繪制 y = x**2 面積圖

# 廁所排隊問題 
# 1、兩場電影結束時間相隔較長,互不影響;
# 2、每場電影結束之后會有20個人想上廁所;
# 3、這20個人會在0到10分鍾之內全部到達廁所);
# 4、每個人上廁所時間在1-3分鍾之間
# 首先模擬最簡單的情況,也就是廁所只有一個位置,不考慮兩人共用的情況則每人必須等上一人出恭完畢方可進行。
# 分析:對於每個人都有如下幾個參數:
# 到達時間 / 等待時間 / 開始上廁所時間 / 結束時間

arrivingtime = np.random.uniform(0,10,size = 20)
arrivingtime.sort()
workingtime = np.random.uniform(1,3,size = 20)
# np.random.uniform 隨機數:均勻分布的樣本值

startingtime = [0 for i in range(20)]
finishtime = [0 for i in range(20)]
waitingtime = [0 for i in range(20)]
emptytime = [0 for i in range(20)]
# 開始時間都是0

#print('arrivingtime\n',arrivingtime,'\n')
#print('workingtime\n',workingtime,'\n')
#print('startingtime\n',startingtime,'\n')
#print('finishtime\n',finishtime,'\n')
#print('waitingtime\n',waitingtime,'\n')
#print('emptytime\n',emptytime,'\n')
print('------')

startingtime[0] = arrivingtime[0]  # 第一個人之前沒有人,所以開始時間 = 到達時間
finishtime[0] = startingtime[0] + workingtime[0]   # 第一個人完成時間 = 開始時間 + “工作”時間
waitingtime[0] = startingtime[0]-arrivingtime[0]   # 第一個人不用等待

for i in range(1,len(arrivingtime)):
    if finishtime[i-1] > arrivingtime[i]:
        startingtime[i] = finishtime[i-1]
    else:
        startingtime[i] = arrivingtime[i]
        emptytime[i] = arrivingtime[i] - finishtime[i-1]
    finishtime[i] = startingtime[i] + workingtime[i]
    waitingtime[i] = startingtime[i] - arrivingtime[i]
    print('第%d個人:到達時間 開始時間 “工作”時間 完成時間 等待時間\n' %i,
          arrivingtime[i],
          startingtime[i],
          workingtime[i],
          finishtime[i],
          waitingtime[i],
         '\n')
print('arerage waiting time is %f' %np.mean(waitingtime))
print('------')
# 判斷:如果下一個人在上一個人完成之前到達,則 開始時間 = 上一個人完成時間,
# 否則 開始時間 = 到達時間,且存在空閑時間 = 到達時間 - 上一個人完成時間

fig = plt.figure(figsize = (6,4))
plt.plot(waitingtime, '-go')
plt.grid(True,linestyle='--', color = 'gray',linewidth = '0.8')
plt.title('蒙特卡羅模擬 - 排隊上廁所問題')
plt.show()
# 圖表繪制

--->>

------
第1個人:到達時間 開始時間 “工作”時間 完成時間 等待時間
 1.47846212718 2.90015955179 2.43550313768 5.33566268947 1.42169742461 

第2個人:到達時間 開始時間 “工作”時間 完成時間 等待時間
 1.50766524856 5.33566268947 1.70026811206 7.03593080153 3.82799744091 

第3個人:到達時間 開始時間 “工作”時間 完成時間 等待時間
 1.68971606051 7.03593080153 2.55933351317 9.59526431469 5.34621474102 

第4個人:到達時間 開始時間 “工作”時間 完成時間 等待時間
 3.22500117584 9.59526431469 2.23730595589 11.8325702706 6.37026313886 

第5個人:到達時間 開始時間 “工作”時間 完成時間 等待時間
 3.68624845537 11.8325702706 1.96298225381 13.7955525244 8.14632181522 

第6個人:到達時間 開始時間 “工作”時間 完成時間 等待時間
 3.748728758 13.7955525244 1.13434491219 14.9298974366 10.0468237664 

第7個人:到達時間 開始時間 “工作”時間 完成時間 等待時間
 3.76353770932 14.9298974366 2.97251793218 17.9024153688 11.1663597273 

第8個人:到達時間 開始時間 “工作”時間 完成時間 等待時間
 4.04448060386 17.9024153688 1.52642253332 19.4288379021 13.8579347649 

第9個人:到達時間 開始時間 “工作”時間 完成時間 等待時間
 5.15292640194 19.4288379021 2.8327295047 22.2615674068 14.2759115002 

第10個人:到達時間 開始時間 “工作”時間 完成時間 等待時間
 6.39798292569 22.2615674068 2.48704326285 24.7486106697 15.8635844811 

第11個人:到達時間 開始時間 “工作”時間 完成時間 等待時間
 6.46150544161 24.7486106697 2.75523182998 27.5038424996 18.287105228 

第12個人:到達時間 開始時間 “工作”時間 完成時間 等待時間
 6.83020450863 27.5038424996 2.82170691612 30.3255494157 20.673637991 

第13個人:到達時間 開始時間 “工作”時間 完成時間 等待時間
 7.54986448877 30.3255494157 1.32813398415 31.6536833999 22.775684927 

第14個人:到達時間 開始時間 “工作”時間 完成時間 等待時間
 7.74933683577 31.6536833999 2.01805818046 33.6717415804 23.9043465641 

第15個人:到達時間 開始時間 “工作”時間 完成時間 等待時間
 8.42722353547 33.6717415804 1.0300259968 34.7017675772 25.2445180449 

第16個人:到達時間 開始時間 “工作”時間 完成時間 等待時間
 8.76080737972 34.7017675772 1.69860652295 36.4003741001 25.9409601974 

第17個人:到達時間 開始時間 “工作”時間 完成時間 等待時間
 9.02778847556 36.4003741001 2.19029299704 38.5906670971 27.3725856245 

第18個人:到達時間 開始時間 “工作”時間 完成時間 等待時間
 9.0683463525 38.5906670971 1.74875934398 40.3394264411 29.5223207446 

第19個人:到達時間 開始時間 “工作”時間 完成時間 等待時間
 9.51437407844 40.3394264411 1.52156911323 41.8609955544 30.8250523627 

arerage waiting time is 15.743466
------

 


免責聲明!

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



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