簡單的SIR模型傳播--numpy/matplotlib(某師範大學學生的期中大作業)
阿新 • • 發佈:2018-12-15
SIR模型是傳染病模型中最經典的模型,其中S表示易感者,I表示感染者,R表示移出者。模型中把傳染病流行範圍內的人群分成三類:S類,易感者(Susceptible),指未得病者,但缺乏免疫能力,與感病者接觸後容易受到感染;I類,感病者(Infective),指染上傳染病的人,它可以傳播給S類成員;R類,移出者(Removal),指被隔離,或因病癒而具有免疫力的人。其中S被附近節點感染的概率為beta,如果S狀態節點有m個I狀態的話,S在下個時間段被感染的概率就是1-(1-beta)^m,如果本身就是I節點,那麼下個階段康復的概率為 u。
然後我們可以用下面程式碼建立ER圖(鄰接矩陣)
def CreateER(N, p): mat = np.random.rand(N, N) mat = np.where(mat>p, 0, 1) for i in range(N): mat[i, i] = 0 mat[i, :] = mat[:, i] return mat
接著我們可以通過計算直方圖來進行區間統計,程式碼如下:
def Distribution(mat):
(a, b) = mat.shape
Count = np.array([mat[i, :].sum() for i in range(a)])
hist = np.histogram(Count, bins=1000, range=(0,1000))
plt.plot(hist[0])
plt.xlabel('degree')
plt.ylabel('p(degree)')
plt.show()
return hist
最終生成相應的SIR模型
# 對一個mat進行一次SIR的傳播 S 1 -- I 2 -- R 3 普通人--1 感染者--2 恢復者 def SIRSpread(mat, beta, mu, vec): nvec = np.array(vec) for i in range(vec.size): if vec[i] == 1: num = 0 for j in range(vec.size): if mat[i,j] == 1 and vec[j] == 2: num = num + 1 prob = 1 - (1-beta)**num rand = random.random() if rand < prob: nvec[i] = 2 elif vec[i] == 2: rand = random.random() if rand < mu: nvec[i] = 3 return nvec # 設定傳播次數,來進行傳播,並返回每個階段S,I,R的數量 def MultiSpread(N, beta, mu, t): mat = CreateER(N, 0.01) vec = np.array([1 for i in range(N)]) rNum = random.randint(0, N-1) vec[rNum] = 2 S = [] I = [] R = [] for i in range(t): vec = SIRSpread(mat, beta, mu, vec) S.append(np.where(np.array(vec)==1, 1, 0).sum()) I.append(np.where(np.array(vec)==2, 1, 0).sum()) R.append(np.where(np.array(vec)==3, 1, 0).sum()) return S,I,R
實驗結果如圖所示