数学建模sir模型python_Python实现简单的SI传播模型

Python实现简单的SI传播模型

9 W1 N' t% O% P% ]9 M#SI疾病传播模型的原理9 k0 t. @& x2 |7 h+ M9 ~* b9 C* X

在经典的传染病模型中,种群(Population)内N个个体的状态可分为如下几类$ K8 m: {+ j- `0 e

4 M) O  A4 `: V1 O& E  U) H" }易感状态(Susceptible)。一个个体在感染前是处于易感状态的,即该个体有可能被邻居个体感染。

% v* X0 d2 ?8 y, Y' ]  p  H易感状态I(Infected)。一个感染上某种病毒的个体就称为是处于感染状态。,即该个体还会以一定概率感染其邻居个体。, y$ b) A  b, V. w& q

移除状态(Remove,Refractory或者Recovered)。也成为免疫状态或恢复状态,当一个个体经历过一个完整的感染周期后,该个体就不再被感染,因此就可以不再考虑改革提。, i& W- F! [! g' H1 U6 c( M

SI传播模型是最简单的疾病传播模型,模型中的所有个体都只可能处于两个状态中的一个

9 C6 U' U" x6 t/ B即易感(S)状态或感染(I)状态。SI模型中的个体一旦被感染后就永远处于感染状态。$ F% e2 @6 C% L) }7 r9 N' _5 I2 q3 R

在给定时刻t,令S(t)与I(t)分别代表该时刻处于易感和感染状态的个体数目,显然有

- z+ e; B6 f: v* q6 N+ PS(t)+I(t)恒等于N,这里,N是个体总数。随着时间t的增长,易感个体与感染个体的接触6 E; w& R. s9 L' J* f3 T

会导致感染个体数量的增加。加入由于个体之间的接触而导致疾病传播的概率为β,疾病仅在; ?+ z5 r) `9 l$ D) P

感染个体和易感个体之间进行接触时才会以概率β将疾病传染给易感个体。在时刻t,易感个体的比例为S(t)/N,感染个体的数量为I(t),一次,易感个体的数量将以如下变化率减少4 Z* N! G# z3 o3 \4 a" u

ds/dt = -β*S(t)I(t)/N

! d6 e4 y2 L) D2 j同时,感染个体的数量会以与易感个体相反的变化率增加,

" S# S( X" Z; Ids/dt = βS(t)*I(t)/N

+ O! N, ?! ]% c2 ^/ j分别将时刻t处于易感状态和感染状态的个体所占比例记为,

: U7 ^! p. B* Bs(t)=S(t)/N5 M3 X$ M) b) T+ Q; }( {

i(t)=I(t)/N6 X. B/ Z; n  N+ c9 E2 D7 w

显然有,- O) u  @3 M% u5 f

s(t)+i(t)恒等于1,此时之前的公式可以记做9 O( Y" B) P! N- k! s) N2 C

ds/dt=-βsi

2 y$ d( k, J6 n8 R& v* Wdi/dt=βsi

; E  P+ N3 F3 S; B" M即

% P0 x7 P7 N. B+ l7 l7 }di/dt=βi(1-i)( t& @1 G* g* I

上式也成为Logistic增长方程式(Logistic growth equation),

4 `3 I( K/ {1 f1 _& G/ O. B方程的解和图像如图9 x- j# @" g( i6 J* k. _

793aa660b5859f2aae3e643587c1d187.gif

2020-4-18 16:14 上传

下载附件 (213.53 KB)

) _& _+ h% s3 K" C5 u& p( e! b! J代码和相关文件以及环境链接:链接:https://pan.baidu.com/s/1JSfHuTPaglFimeEBLdSDyQ

% e+ k$ p) k6 `" e: L" S提取码:z448

% {* z: G7 ?4 q; [2 L

0 E' l' j9 l* P' m9 A) M9 ]$ z2 ~0 Q/ a0 {. p+ @

'''

4 t9 E" Q4 }) ?实验环境Python2.7.13,igraph包,cairo包,numpy包

4 t$ q# o  U9 X% A  V'''

1 Z: ?2 ]& |7 ~. ?4 T# -*- coding:utf8 -*

9 y- ~/ K% b2 |, R% L2 Hfrom igraph import *

6 j, Q1 U% X3 y# y% b: F) Z6 yimport numpy as numpy0 ^2 F' z  G9 q

from  numpy import *% J7 {( ?- t, C: Q

import random

# m; n: M/ ~9 D* k0 T

$ d! ~7 Q* J' W: ^: ?, Tdef len_arr(infected_array,nodes_num):#获取感染数组长度

8 `3 i3 }4 ]; P* H: s5 {3 j1 M    len_value=0#初始化长度

7 i' z1 I9 X1 y4 P' w    len_value=nodes_num-infected_array.count(-1)#被感染数量是结点总数减去未感染节点数(未感染的结点被标记为-1)

/ U8 f% x: M7 F( j' r) h    return len_value# r0 y7 D* h2 R6 m2 A

. f0 R; M/ g- B- m* t* P4 Ng=Graph.Read_GML("C:\python27\e1.gml")#将本地保存的网络数据读入变量g(生成图)( O0 M" J7 l  A7 q6 z" `; f9 m

summary(g)# Y2 B& L4 O' g. L( K! V1 d% o8 K' w

nodes_num=g.vcount()#统计图中的结点个数

$ h) k' c/ |9 y' t3 O  X/ P, knet_mat=g.get_adjacency(type=GET_ADJACENCY_BOTH)#将网络数据转换为邻接矩阵存储在变量net_mat- F. J& f% `7 P* U. A" Q

g.vs["color"]=["white"]#给图的顶点序列颜色赋值白色+ @7 _% ^/ u" C  K

a=[arange(nodes_num)+1]*3#声明一个N行3列的数组a

* ]8 @% M  O3 l- D1 mnodes_state=matrix(a).T#nodes_state通过转置a矩阵创建,用于存放每个节点的状态信息以及其被感染的时间(这个是理解算法的重中之重!!!)6 Q6 X4 V; M" ?

#第一列是节点编号,第二列是节点状态,感染状态用-2表示,第三列是节点感染的时间# K# {# _$ }0 q$ p

print(nodes_state)

% g( W$ H) ~5 s/ F( cinfected_array=[-1]*34#用于存放本轮被感染的结点, 这些结点将参与下一次感染   34代表网络节点数

! R! {1 `# x$ s2 `print(infected_array)9 Z8 Q, F( y4 v+ q/ f% ?

+ G& x! n  E7 w! s/ ?$ ^( Y* {0 J- l8 ?infe_rate=1#传播率(感染率) 1代表邻接点100%被感染

/ j% y' j, i( y: b, Lset_time=2#传播次数(感染次数) 2次% K$ z( F( _8 l

source_seed=1#感染源位置

' O, N- _0 a1 N' `1 m* A3 W$ c% wnodes_state[0:nodes_num,2]=-1#给所有节点初始化感染时间为-1

9 p, A/ e; ?8 Pnodes_state[source_seed-1,1]=-2#设置第一个感染源感染状态 -2代表感染状态

! Q; s7 u. |7 M  E& @1 E( onodes_state[source_seed-1,2]=1#设置第一个感染源的感染时间为1

$ D% P5 A+ v0 H2 p. _5 Hg.vs[source_seed-1]["color"]="red"#将感染的顶点颜色标红% y8 [& ], b% j& e2 o  O

infected_array[0]=source_seed#将感染源的位置存入被感染节点列表3 G8 B$ m  n8 ]4 r# }

plot(g)#绘制

, B( {& B0 c, l+ {: i* K  j" Y7 F, E' A

stop=False#感染过程结束的标记+ l) r8 x9 t" y$ s) P

temp_time=0#第几次感染

, Z+ ~. x+ m+ `( u# H4 k" rtemp_len=0#本轮的感染源数量初始化- |" ], w# z4 `( y* r, }  N) ~/ j

, _4 w( P2 ~2 j. M( v8 Xwhile not stop:# P& P1 e4 q* I: i

i=0#记录让每个感染源都传播一次

; m* m: y3 E( L1 ]* N4 m    if len_arr(infected_array,nodes_num)>0 and len_arr(infected_array,nodes_num)<=nodes_num:#感染可以进行7 U1 i  ]& ?5 Y8 T

temp_len=len_arr(infected_array,nodes_num)#获取本轮的感染源数量

$ F/ _3 K- C4 T4 v$ ]9 a- R        while i

7 e0 y- j, V2 v' c# F- Y            temp_time=nodes_state[infected_array-1,2]#获取每一个节点的感染时间' y* b% g' S0 X1 k

nei_count=0#下一轮可以被感染到的节点数量

# m  y# n' q* j- Y# ^            #生成下一轮可能被感染的节点的集合nei_arr

- ~0 T  f! ?+ G/ U2 F3 Q            for j in range(nodes_num):#遍历节点

8 f+ |5 c7 i3 k- T: R                if net_mat[infected_array-1,j]==1 and nodes_state[j,1]!=-2:#是邻接节点而且未被感染4 x. p0 y: A3 d$ e  v' b+ V$ D

nei_count=nei_count+1#下一轮可以被感染到的节点数量++. A+ m8 d+ D) }/ k" a

nei_arr=[-1]*nei_count#用于临时存放本轮被感染的结点, 这些结点将参与下一次感染. Q7 W, K9 L6 e" `' V8 B! r

t=0

+ {3 [: n4 t- F3 w$ n: V. u            for j in range(nodes_num):

' f- L5 b8 h' E5 O. c* {) F                if net_mat[infected_array-1,j]==1 and nodes_state[j,1]!=-2:3 H1 |& L  J; m( w

nei_arr[t]=j+15 V) f/ a' b2 \  L7 Q! r2 M

t=t+1

$ k: q* r6 v/ v- d/ l; i. y            ran_infe_arr=random.sample(range(nei_count),int(nei_count*infe_rate))#随机生成会被感染的节点的数组4 ^# E6 x& B4 u9 c0 W

#random.simple(arg1,num) 从arg1集合中随机取num个数据生成一个对象

. z/ R* l; S3 ^& ?0 l            if len(ran_infe_arr)>0:#存在需要被感染的节点; Z6 Z4 P: N2 g2 I; X1 U

t=0#让ran_infe_arr内每个感染源都被感染9 I8 t3 O& r. z0 i

while t

* T  q6 V& c+ s* {                    nodes_state[nei_arr[ran_infe_arr[t]]-1,1]=-2#标记为感染状态, u: `% L* Q7 }4 ?8 k

nodes_state[nei_arr[ran_infe_arr[t]]-1,2]=temp_time+1#记录感染时间

# F* M2 g* ^4 K1 U& r* g                    infected_array[len_arr(infected_array,nodes_num)]=nei_arr[ran_infe_arr[t]]#将此次感染节点放入总的感染节点数组中$ L8 T6 h: O" A0 ~+ ~, X" e

g.vs[nei_arr[ran_infe_arr[t]]-1]["color"]="pink"#将此次感染的节点集的所有节点颜色置为粉色7 v+ q+ C8 w$ Y2 \, d. @

plot(g)#绘制

" v; C# H# J4 @                    t=t+1. u# }& F+ g4 h) ^

i=i+1

: j2 \" ^/ ?$ w    if temp_time>set_time-1:#当执行感染的次数等于设置的次数结束感染

3 b0 h  B) w" ?; `1 C. Z: Z        stop=True - ~& r2 G+ Y. r1 L% Z, ^

- x% y, C3 f1 |( y/ S0 P# C0 R3 ?& ^. ?7 p

视频演示bilibili传送门- g  E( t+ L# c9 l+ e$ Z; K7 p

效果图

# S) s2 @3 S! x8 E' C

1 M! Z+ M0 e$ l

) G6 z1 P: i8 n! J

793aa660b5859f2aae3e643587c1d187.gif

2020-4-18 16:15 上传

下载附件 (174.22 KB)

0 y+ G# M/ P; X

; L/ |( N2 h; G+ _

793aa660b5859f2aae3e643587c1d187.gif

2020-4-18 16:15 上传

下载附件 (22.44 KB)

6 Z7 t, V4 P* R) D% V5 ]1 J# C# a! r1 q+ e* \- y( j' i9 f

793aa660b5859f2aae3e643587c1d187.gif

2020-4-18 16:16 上传

下载附件 (42.85 KB)

: \" L" @1 l" _$ K' E* N. ]

\1 ?. b( N; E0 L0 H0 @, T  `* y% z

793aa660b5859f2aae3e643587c1d187.gif

2020-4-18 16:16 上传

下载附件 (17.44 KB)

9 B$ n8 d% E+ x. c3 W

( ^+ Y& c- b6 {5 }

793aa660b5859f2aae3e643587c1d187.gif

2020-4-18 16:16 上传

下载附件 (19.78 KB)

/ g- X8 I: a! v  n% k+ C

* m# e; D, V& X6 i3 G% ?$ U

793aa660b5859f2aae3e643587c1d187.gif

2020-4-18 16:16 上传

下载附件 (21.16 KB)

————————————————7 z' i) m% X. e7 H- t5 \: D

版权声明:本文为CSDN博主「eck_燃」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。* @+ z( Z8 N/ d3 G, v

原文链接:https://blog.csdn.net/wdays83892469/article/details/80878862

! N% ^7 P5 m- E

8 _) @$ w5 B9 `; a1 T9 U- y1 @; X+ a( S( \6 O0 J6 N! f$ @


版权声明:本文为weixin_42297843原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。