数学建模社区-数学中国
标题:
Python实现简单的SI传播模型
[打印本页]
作者:
杨利霞
时间:
2020-4-18 16:16
标题:
Python实现简单的SI传播模型
Python实现简单的SI传播模型
4 @9 ?, [ S, R# S
#SI疾病传播模型的原理
' B- _+ S' G. O4 s# k9 \! {1 i
在经典的传染病模型中,种群(Population)内N个个体的状态可分为如下几类
* I3 r4 y: X3 w; t/ q7 E2 d
" H; @/ ~3 u0 q; ^, C& O$ j
易感状态(Susceptible)。一个个体在感染前是处于易感状态的,即该个体有可能被邻居个体感染。
6 ^, l F( R/ q: s3 E+ E
易感状态I(Infected)。一个感染上某种病毒的个体就称为是处于感染状态。,即该个体还会以一定概率感染其邻居个体。
( C: V4 [ t7 m' ^
移除状态(Remove,Refractory或者Recovered)。也成为免疫状态或恢复状态,当一个个体经历过一个完整的感染周期后,该个体就不再被感染,因此就可以不再考虑改革提。
0 }% g5 m+ _1 E" z; v0 Z
SI传播模型是最简单的疾病传播模型,模型中的所有个体都只可能处于两个状态中的一个
5 u8 }( j# f1 G9 `8 Z1 B+ P0 ]
即易感(S)状态或感染(I)状态。SI模型中的个体一旦被感染后就永远处于感染状态。
# _4 i- _7 Y9 ?& c P9 s( S
在给定时刻t,令S(t)与I(t)分别代表该时刻处于易感和感染状态的个体数目,显然有
0 G& e' E0 B( q' z: k2 F7 g
S(t)+I(t)恒等于N,这里,N是个体总数。随着时间t的增长,易感个体与感染个体的接触
$ k, [; Z Z3 C2 H
会导致感染个体数量的增加。加入由于个体之间的接触而导致疾病传播的概率为β,疾病仅在
3 q6 z2 ?' G, A% B- ^
感染个体和易感个体之间进行接触时才会以概率β将疾病传染给易感个体。在时刻t,易感个体的比例为S(t)/N,感染个体的数量为I(t),一次,易感个体的数量将以如下变化率减少
6 I: c, d0 [# G' I
ds/dt = -β*S(t)I(t)/N
: r9 f* h9 J+ K5 @) _; r5 O
同时,感染个体的数量会以与易感个体相反的变化率增加,
* k+ U' b; H7 {# {8 Z2 @
ds/dt = βS(t)*I(t)/N
; O0 \+ q3 \9 Z1 l) k" P4 ?
分别将时刻t处于易感状态和感染状态的个体所占比例记为,
q8 s+ p& t2 V$ }' \/ D1 |
s(t)=S(t)/N
" K1 M9 s1 Y( s, N& q x
i(t)=I(t)/N
( [1 ?6 t5 l6 }* ~
显然有,
( N( I. o6 `/ A
s(t)+i(t)恒等于1,此时之前的公式可以记做
! F9 q6 ^6 g: ~; |
ds/dt=-βsi
% m5 z# {( m' }6 Y2 ~; w
di/dt=βsi
3 p7 p* s+ [4 g$ A5 Z3 |
即
8 S+ k! q, A, J; Q" \% {
di/dt=βi(1-i)
7 l6 x! ?! i {) a# w* r- J
上式也成为Logistic增长方程式(Logistic growth equation),
6 O; D: _$ t) j& Z& |7 L4 L1 S
方程的解和图像如图
3 n/ s4 W& T" x: I) K
2020-4-18 16:14 上传
下载附件
(213.53 KB)
# \1 F) b% v) q, O" W' T4 R" K8 {2 N
代码和相关文件以及环境链接:链接:https://pan.baidu.com/s/1JSfHuTPaglFimeEBLdSDyQ
; ^, F2 }9 j. |% J; a! ]( A
提取码:z448
. w. J; x6 i" g7 b0 ]
0 \. t) `* V! G4 Z& c& E4 u) w
6 f) i+ F7 g! G& q
'''
( g h% z4 G( M3 C9 t: O3 Z
实验环境Python2.7.13,igraph包,cairo包,numpy包
( t4 |* C J. |; w" g J3 v
'''
* K* t- ?9 M7 b7 L" F. J4 N
# -*- coding:utf8 -*
% T; N7 q, L+ y
from igraph import *
. B j0 r- U+ B% `6 U1 D
import numpy as numpy
7 v/ B( I" \# \7 Y6 K2 q
from numpy import *
# m) _/ L7 A! }! [4 V8 ]% o# d
import random
: V7 _# r* |6 f: ]9 _
0 ]% ?1 z5 z7 j% y5 O
def len_arr(infected_array,nodes_num):#获取感染数组长度
- I) w b- G3 F+ f0 j/ ^
len_value=0#初始化长度
1 {4 _: z! _, i
len_value=nodes_num-infected_array.count(-1)#被感染数量是结点总数减去未感染节点数(未感染的结点被标记为-1)
& i% j9 z: Z+ i
return len_value
! u4 K0 g; x2 ~
3 x( u' N% P% t$ \3 G, P6 o
g=Graph.Read_GML("C:\python27\e1.gml")#将本地保存的网络数据读入变量g(生成图)
* u& u( }# P4 c
summary(g)
: t3 q! A) S8 L: j1 G+ s5 R1 }3 C
nodes_num=g.vcount()#统计图中的结点个数
: A* L3 w0 s2 Y; U: w
net_mat=g.get_adjacency(type=GET_ADJACENCY_BOTH)#将网络数据转换为邻接矩阵存储在变量net_mat
. t* T2 W6 t* \( Q# Z
g.vs["color"]=["white"]#给图的顶点序列颜色赋值白色
' R! Q! p. f. b$ s8 j
a=[arange(nodes_num)+1]*3#声明一个N行3列的数组a
* @' t. f+ }2 }+ J; J6 R
nodes_state=matrix(a).T#nodes_state通过转置a矩阵创建,用于存放每个节点的状态信息以及其被感染的时间(这个是理解算法的重中之重!!!)
2 L' d3 Z) _* b" Z& b9 N
#第一列是节点编号,第二列是节点状态,感染状态用-2表示,第三列是节点感染的时间
) n2 S$ I2 K7 n a
print(nodes_state)
2 X3 A. |3 p4 C# \
infected_array=[-1]*34#用于存放本轮被感染的结点, 这些结点将参与下一次感染 34代表网络节点数
7 i T0 K$ D( Y! a3 r/ e
print(infected_array)
4 F4 d! ]( y! c5 d4 y
5 k/ y" Z9 P, Q" T+ V6 o, t
infe_rate=1#传播率(感染率) 1代表邻接点100%被感染
1 d1 C6 M6 X U; K s9 |
set_time=2#传播次数(感染次数) 2次
, }" L. o# t( w7 E
source_seed=1#感染源位置
, j" H( b% Q2 [" ]
nodes_state[0:nodes_num,2]=-1#给所有节点初始化感染时间为-1
9 j; @/ X g" F8 X: R- |
nodes_state[source_seed-1,1]=-2#设置第一个感染源感染状态 -2代表感染状态
6 C/ W3 ?) j+ r0 J: a1 K5 P) Y
nodes_state[source_seed-1,2]=1#设置第一个感染源的感染时间为1
- o7 |5 P: A& z
g.vs[source_seed-1]["color"]="red"#将感染的顶点颜色标红
4 C% Y" ~& e8 i" N
infected_array[0]=source_seed#将感染源的位置存入被感染节点列表
. C4 a; m }: m. {& Q/ [
plot(g)#绘制
/ Y+ _4 f2 ], h+ N k
8 \: C5 @. A; r
stop=False#感染过程结束的标记
! L3 x0 A6 g: b! [
temp_time=0#第几次感染
! N0 s$ g' f# x J/ n
temp_len=0#本轮的感染源数量初始化
! s8 _1 Z( `/ v$ n
) L" ?: i: e, \9 K8 [# c
while not stop:
0 C1 W" Z2 u+ A/ L7 H) J+ g
i=0#记录让每个感染源都传播一次
, W# C9 f$ v: i& X; q, G
if len_arr(infected_array,nodes_num)>0 and len_arr(infected_array,nodes_num)<=nodes_num:#感染可以进行
* G8 x# w% w5 Z G% P9 f2 W4 N) x* G1 v
temp_len=len_arr(infected_array,nodes_num)#获取本轮的感染源数量
3 c! V0 ~: {/ d6 a4 W" t" V3 l: v
while i<temp_len:
1 i5 ~% V. b. C2 w' {: L
temp_time=nodes_state[infected_array
-1,2]#获取每一个节点的感染时间
; y* @/ ~2 w9 d% `3 u
nei_count=0#下一轮可以被感染到的节点数量
2 j; m7 d2 G1 O% r7 o" Y
#生成下一轮可能被感染的节点的集合nei_arr
: e0 `( A8 ^, A- W' U1 x1 W
for j in range(nodes_num):#遍历节点
. o& b+ n% }9 n- V" y
if net_mat[infected_array
-1,j]==1 and nodes_state[j,1]!=-2:#是邻接节点而且未被感染
% D$ z2 G% ~3 [0 y6 x$ [6 f' T
nei_count=nei_count+1#下一轮可以被感染到的节点数量++
' r2 _0 W6 Q) x- M. r6 O
nei_arr=[-1]*nei_count#用于临时存放本轮被感染的结点, 这些结点将参与下一次感染
* z h& [* O4 L
t=0
* p# k* L( Y! A0 q; r
for j in range(nodes_num):
9 i2 i- d: \, a' [2 f
if net_mat[infected_array
-1,j]==1 and nodes_state[j,1]!=-2:
; h% N% A; ~. e2 ^! l
nei_arr[t]=j+1
$ \2 N. t9 x' c8 n8 ~
t=t+1
# T7 j N* |, m: O# |4 u3 P
ran_infe_arr=random.sample(range(nei_count),int(nei_count*infe_rate))#随机生成会被感染的节点的数组
. O% F2 d0 u& M7 R
#random.simple(arg1,num) 从arg1集合中随机取num个数据生成一个对象
9 q- L# P9 _: ]+ `' q
if len(ran_infe_arr)>0:#存在需要被感染的节点
! T( y; |- i3 N6 F+ m
t=0#让ran_infe_arr内每个感染源都被感染
4 T. T/ @4 D! n3 m- J: R
while t<len(ran_infe_arr):#对刚才生成的会被感染的数组内的节点进行感染
B* \8 l0 q2 ]& D" F
nodes_state[nei_arr[ran_infe_arr[t]]-1,1]=-2#标记为感染状态
1 R7 p# c' j7 u* N8 \
nodes_state[nei_arr[ran_infe_arr[t]]-1,2]=temp_time+1#记录感染时间
Y. T6 `# Z5 d3 x. A
infected_array[len_arr(infected_array,nodes_num)]=nei_arr[ran_infe_arr[t]]#将此次感染节点放入总的感染节点数组中
! C! {0 R) v( e3 C/ i( P' w
g.vs[nei_arr[ran_infe_arr[t]]-1]["color"]="pink"#将此次感染的节点集的所有节点颜色置为粉色
! z3 L/ n4 q5 j0 K
plot(g)#绘制
& b. q1 y) Q6 m+ m( ]7 a& T6 W
t=t+1
0 R, N+ e3 r1 f
i=i+1
2 l4 C/ c0 F; h6 I0 T" ~
if temp_time>set_time-1:#当执行感染的次数等于设置的次数结束感染
1 d! j+ j8 x! R/ w2 ?3 o. W9 V$ T
stop=True
. g) {. \* u3 @. O: h6 W% h
! L9 L3 ^$ I; t) J# n
. r5 u8 U" I4 S. s7 K
视频演示bilibili传送门
( h+ S! ?6 x2 Q
效果图
1 n& H) e# A4 ]8 p w; m: O
1 O5 A% b5 F0 u4 E
. J2 ~5 v1 v, [6 U! H
2020-4-18 16:15 上传
下载附件
(174.22 KB)
% k3 y. z: |2 `3 T% P3 p* _& Q
7 L* C2 P3 J4 y- z
2020-4-18 16:15 上传
下载附件
(22.44 KB)
4 K k" C8 i( W8 W3 ^
" D# P l" ?3 j/ X: U- u
2020-4-18 16:16 上传
下载附件
(42.85 KB)
, f+ r; d `8 O. r5 D* C
( P/ ]& t2 v- |& T9 x; A" G
2020-4-18 16:16 上传
下载附件
(17.44 KB)
$ p! k* ]1 n* \7 S
: S% {' ]6 {7 ]2 t6 y) O u7 g
2020-4-18 16:16 上传
下载附件
(19.78 KB)
1 x. E6 s1 k/ f( W4 p0 @- J
$ v3 z/ n: z" {- I4 m# Y: P
2020-4-18 16:16 上传
下载附件
(21.16 KB)
————————————————
) U* v+ b K. K/ W$ s" D
版权声明:本文为CSDN博主「eck_燃」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
- Q- d, {6 X6 _% N& O
原文链接:https://blog.csdn.net/wdays83892469/article/details/80878862
" C" _- h; L3 |% O
' s+ \( P- N: ?/ q7 s# j6 z/ q
$ f9 s/ u& u- G
作者:
尔雅
时间:
2020-4-18 17:50
发表回复棒!
/ I% D3 n/ A4 V( A0 M; [, \' r5 U
欢迎光临 数学建模社区-数学中国 (http://www.madio.net/)
Powered by Discuz! X2.5