数学建模社区-数学中国

标题: Python实现简单的SI传播模型 [打印本页]

作者: 杨利霞    时间: 2020-4-18 16:16
标题: Python实现简单的SI传播模型
Python实现简单的SI传播模型) q% q" p4 A, B* {0 U2 `
#SI疾病传播模型的原理
# P) C, h3 X* a5 B5 s在经典的传染病模型中,种群(Population)内N个个体的状态可分为如下几类5 `) P8 b; _+ D- A1 l6 J4 p

# x0 b( V/ p% W7 R) ~+ Q$ I3 ^易感状态(Susceptible)。一个个体在感染前是处于易感状态的,即该个体有可能被邻居个体感染。
6 d* E' D% a  g" l易感状态I(Infected)。一个感染上某种病毒的个体就称为是处于感染状态。,即该个体还会以一定概率感染其邻居个体。
- f0 t& i' u7 Y移除状态(Remove,Refractory或者Recovered)。也成为免疫状态或恢复状态,当一个个体经历过一个完整的感染周期后,该个体就不再被感染,因此就可以不再考虑改革提。4 _# z# @# P3 K$ l
SI传播模型是最简单的疾病传播模型,模型中的所有个体都只可能处于两个状态中的一个
% `& u" a! O) k, f( d$ @. Q即易感(S)状态或感染(I)状态。SI模型中的个体一旦被感染后就永远处于感染状态。# N! X: k% }/ R
在给定时刻t,令S(t)与I(t)分别代表该时刻处于易感和感染状态的个体数目,显然有
. z' `; k6 w4 e% j' I# Z$ [  }S(t)+I(t)恒等于N,这里,N是个体总数。随着时间t的增长,易感个体与感染个体的接触' Z! }) J" Y+ M+ }  {  i- h
会导致感染个体数量的增加。加入由于个体之间的接触而导致疾病传播的概率为β,疾病仅在4 s# l: z' P; h8 D/ A. q
感染个体和易感个体之间进行接触时才会以概率β将疾病传染给易感个体。在时刻t,易感个体的比例为S(t)/N,感染个体的数量为I(t),一次,易感个体的数量将以如下变化率减少5 w) t) l2 m) P0 m% d' p
ds/dt = -β*S(t)I(t)/N
3 I4 i$ V1 S9 Y. e同时,感染个体的数量会以与易感个体相反的变化率增加,
+ `' {4 [$ {2 N- \$ \8 \. S4 d$ Ods/dt = βS(t)*I(t)/N) Y( w( k2 Q' e7 @5 l3 ~. f6 Q( |+ G
分别将时刻t处于易感状态和感染状态的个体所占比例记为,4 A& _8 W) P9 k
s(t)=S(t)/N
( z. L5 V( F" ]/ R' @1 Ei(t)=I(t)/N, |% N# A$ t0 _
显然有,4 \# H' V3 Q4 }- l+ P) p, {
s(t)+i(t)恒等于1,此时之前的公式可以记做6 {5 S5 `$ u" X! J1 T& c3 m3 d/ ^
ds/dt=-βsi2 d6 E( m3 i* Z0 ^: Z
di/dt=βsi6 y: t" P; }  `
8 n  O* R" V9 |2 o
di/dt=βi(1-i)5 P/ p$ ]$ e0 z* C2 q# u  \
上式也成为Logistic增长方程式(Logistic growth equation),
- I3 Z2 K" B+ J( b2 R5 d: x# i方程的解和图像如图8 f1 v# O! Z, f% E
1.jpg
( P: U( V6 f) i7 J% G代码和相关文件以及环境链接:链接:https://pan.baidu.com/s/1JSfHuTPaglFimeEBLdSDyQ
! J) l: j8 h) P+ `, C提取码:z4483 d8 s7 Y! P  P% ~0 F4 x

  n- |; ?: q6 G9 V4 a6 {4 g7 H! A+ ]! M4 h) f
'''$ v4 [1 F9 p, I/ K6 J& _. m
实验环境Python2.7.13,igraph包,cairo包,numpy包8 K; ]' T  Q6 g: O- f
'''
) l+ T* j, g3 Z+ a- h# -*- coding:utf8 -*' M0 F# E! M! v* e1 {& T
from igraph import *
% @3 b1 c3 \4 \7 ^import numpy as numpy
8 Z" L2 H( J6 K$ D- c/ Bfrom  numpy import *6 ^) b, h  `8 ?, D. l. Z
import random. ~" e; g$ F1 Q, |
; r2 m8 [+ l8 @/ g
def len_arr(infected_array,nodes_num):#获取感染数组长度
1 m9 z% U! I" r0 ~    len_value=0#初始化长度
. e& M) Q8 h2 h' V* i    len_value=nodes_num-infected_array.count(-1)#被感染数量是结点总数减去未感染节点数(未感染的结点被标记为-1)
  h, O  ?7 h* C; N7 r& O3 w    return len_value) [7 j  Q- f- o5 C1 t. n" \
  C# T5 L0 E' F
g=Graph.Read_GML("C:\python27\e1.gml")#将本地保存的网络数据读入变量g(生成图)* a, p4 @# e( h* A) d
summary(g)) D! b4 {" f; i0 n
nodes_num=g.vcount()#统计图中的结点个数
- u; X$ z/ m! Inet_mat=g.get_adjacency(type=GET_ADJACENCY_BOTH)#将网络数据转换为邻接矩阵存储在变量net_mat
/ V2 m4 w; w& a1 n9 kg.vs["color"]=["white"]#给图的顶点序列颜色赋值白色6 ]* u1 A/ Z: x5 y
a=[arange(nodes_num)+1]*3#声明一个N行3列的数组a
: i7 N* J" s. |5 z2 ]9 j& anodes_state=matrix(a).T#nodes_state通过转置a矩阵创建,用于存放每个节点的状态信息以及其被感染的时间(这个是理解算法的重中之重!!!)% ?+ s' r4 P% P3 s
                                                    #第一列是节点编号,第二列是节点状态,感染状态用-2表示,第三列是节点感染的时间7 G9 s- W0 [  Y5 |* e$ w  O2 N
print(nodes_state)1 o1 E6 v6 F  z: o" u
infected_array=[-1]*34#用于存放本轮被感染的结点, 这些结点将参与下一次感染   34代表网络节点数' D; ^, |  @+ z" A
print(infected_array)
# |5 B5 [. D( r' X" M. Z8 F" n* L
. |+ ?! S1 B/ h5 j- Vinfe_rate=1#传播率(感染率) 1代表邻接点100%被感染
* H% M: |8 R. `4 d( |. t+ Dset_time=2#传播次数(感染次数) 2次0 N  |- b7 V1 i$ D/ M+ w) X
source_seed=1#感染源位置
; v# d! x% v: o' m' r! K  Snodes_state[0:nodes_num,2]=-1#给所有节点初始化感染时间为-1: Z: }8 G. F4 K* |& I; `8 ^9 E: Y; {% R
nodes_state[source_seed-1,1]=-2#设置第一个感染源感染状态 -2代表感染状态" i& h' d6 P7 U7 H8 Q; G) l" m9 }' X
nodes_state[source_seed-1,2]=1#设置第一个感染源的感染时间为1
/ m2 {9 H  b) W; _2 Ug.vs[source_seed-1]["color"]="red"#将感染的顶点颜色标红
, C) E: o; F4 i) ]6 zinfected_array[0]=source_seed#将感染源的位置存入被感染节点列表
( R9 n: p- y. p& D/ r$ d6 [5 h, j5 rplot(g)#绘制' _5 T0 [) `- J( p% ^

6 ^3 U& j4 I/ D# p* }stop=False#感染过程结束的标记% v; a1 u+ p  d7 b9 `/ P( L
temp_time=0#第几次感染
8 P' Z0 k; X6 _% r/ ]9 {* {/ Ktemp_len=0#本轮的感染源数量初始化. z) h$ M5 H  f1 [
1 G; w7 x8 B2 S! C6 ~% ]% G  \
while not stop:
3 |. M9 D& Y$ ]5 B, e5 u8 G    i=0#记录让每个感染源都传播一次
& {4 l6 W+ \+ O- g: Q0 |+ T    if len_arr(infected_array,nodes_num)>0 and len_arr(infected_array,nodes_num)<=nodes_num:#感染可以进行
/ W4 D9 Y+ u# @% N8 U# D  s* ?# T        temp_len=len_arr(infected_array,nodes_num)#获取本轮的感染源数量% m* Z4 S2 [2 ]8 p9 M
        while i<temp_len:: ~- _# U/ o  @9 c% ~
            temp_time=nodes_state[infected_array-1,2]#获取每一个节点的感染时间% k% [: ]5 W- T  X% l: f1 {3 B; E0 l
            nei_count=0#下一轮可以被感染到的节点数量; z4 j6 w1 S9 e  ~
            #生成下一轮可能被感染的节点的集合nei_arr% E: c: {; T4 C4 G
            for j in range(nodes_num):#遍历节点: F# y6 P4 l/ N: ]1 x" F: q
                if net_mat[infected_array-1,j]==1 and nodes_state[j,1]!=-2:#是邻接节点而且未被感染
- C, [) d  w3 u! ^/ Z                    nei_count=nei_count+1#下一轮可以被感染到的节点数量++
$ F; ~- [1 I$ L' D2 p) u! E; v            nei_arr=[-1]*nei_count#用于临时存放本轮被感染的结点, 这些结点将参与下一次感染( S' p! x8 u, E) Y& u
            t=0* v/ \! }, ^1 R
            for j in range(nodes_num):
+ O; j7 ?- b  E4 u+ _  v9 L/ T                if net_mat[infected_array-1,j]==1 and nodes_state[j,1]!=-2:5 p7 ~' @1 o9 \$ d3 n/ C
                    nei_arr[t]=j+1' r0 s' z, i+ X: w! i& ~
                    t=t+10 w: J( C0 i$ l  e6 b
            ran_infe_arr=random.sample(range(nei_count),int(nei_count*infe_rate))#随机生成会被感染的节点的数组
% u4 _1 k! B* O0 e* F9 v                                        #random.simple(arg1,num) 从arg1集合中随机取num个数据生成一个对象, U6 n9 p8 Z7 `" [% F, L
            if len(ran_infe_arr)>0:#存在需要被感染的节点+ y" d! w# _: E$ `
                t=0#让ran_infe_arr内每个感染源都被感染9 F2 y( b: Q5 S9 \4 I; W4 J  Y
                while t<len(ran_infe_arr):#对刚才生成的会被感染的数组内的节点进行感染
4 c& L, B: `$ M9 j1 ~                    nodes_state[nei_arr[ran_infe_arr[t]]-1,1]=-2#标记为感染状态
) s" l& d: Y5 d' }                    nodes_state[nei_arr[ran_infe_arr[t]]-1,2]=temp_time+1#记录感染时间
  q  }) c* y3 R2 q. V, [) z                    infected_array[len_arr(infected_array,nodes_num)]=nei_arr[ran_infe_arr[t]]#将此次感染节点放入总的感染节点数组中
! [7 J# L. _; N                    g.vs[nei_arr[ran_infe_arr[t]]-1]["color"]="pink"#将此次感染的节点集的所有节点颜色置为粉色
% v( e5 `( N+ T( i  h4 ]) O                    plot(g)#绘制* d& E, \5 U+ E/ U1 \
                    t=t+12 L- S; @# n" B# j' E" j
            i=i+11 o  I, {+ m" R2 w+ Y( P
    if temp_time>set_time-1:#当执行感染的次数等于设置的次数结束感染/ v& F' y4 y; N
        stop=True 3 V; y% W0 ~3 e* v+ n7 H5 k
0 @! _, c' _3 R% }: Y. \2 S
- @, I" t* |0 o4 b3 c
视频演示bilibili传送门; O9 a# e3 |9 Q: K2 s& I
效果图
/ B) W8 i1 c4 Y2 h/ u  F( N" d/ B9 g8 g. k% k, P
: o& y/ k. s+ [# T
2.jpg
. R" T2 [! k) L, D# H
( }% z& z& E; @; g" d* g 3.png 4 d2 |9 [( ^9 t& D! Z
2 v0 {; S$ a$ Z- B& T. e9 j
4.jpg 0 T9 f7 m4 a8 p

. m: a; w5 Y% K0 |) X+ t) K0 l 5.png # m7 @6 }9 u% k! @. b

) D: k' n) W1 U 6.png ) u# t$ g" Q  d

2 D. v; _( O0 a! ^ 7.png ————————————————
  v. N4 E% }! s* b9 a- B) W9 U版权声明:本文为CSDN博主「eck_燃」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
5 t7 O, e: @7 n. r( }原文链接:https://blog.csdn.net/wdays83892469/article/details/80878862) ], n. e$ y/ F6 y1 _

3 Q8 w8 h! S% K" l  G0 M  ~6 z3 o0 g" S4 z& C

作者: 尔雅    时间: 2020-4-18 17:50
发表回复棒!
' J. N7 w  S2 J+ I* B




欢迎光临 数学建模社区-数学中国 (http://www.madio.net/) Powered by Discuz! X2.5