- 在线时间
- 1630 小时
- 最后登录
- 2024-1-29
- 注册时间
- 2017-5-16
- 听众数
- 82
- 收听数
- 1
- 能力
- 120 分
- 体力
- 563407 点
- 威望
- 12 点
- 阅读权限
- 255
- 积分
- 174245
- 相册
- 1
- 日志
- 0
- 记录
- 0
- 帖子
- 5313
- 主题
- 5273
- 精华
- 3
- 分享
- 0
- 好友
- 163
TA的每日心情 | 开心 2021-8-11 17:59 |
|---|
签到天数: 17 天 [LV.4]偶尔看看III 网络挑战赛参赛者 网络挑战赛参赛者 - 自我介绍
- 本人女,毕业于内蒙古科技大学,担任文职专业,毕业专业英语。
 群组: 2018美赛大象算法课程 群组: 2018美赛护航培训课程 群组: 2019年 数学中国站长建 群组: 2019年数据分析师课程 群组: 2018年大象老师国赛优 |
Python实现简单的SI传播模型
/ j9 h5 D# T( N1 K#SI疾病传播模型的原理
6 u9 v; s/ |. J: g1 b1 b' S1 D7 ?在经典的传染病模型中,种群(Population)内N个个体的状态可分为如下几类
; {% q8 S, P E) s6 Y o% ^( U9 S; N ^9 ^
易感状态(Susceptible)。一个个体在感染前是处于易感状态的,即该个体有可能被邻居个体感染。6 l1 `4 u; L+ V6 |! E: }+ Y4 }* f
易感状态I(Infected)。一个感染上某种病毒的个体就称为是处于感染状态。,即该个体还会以一定概率感染其邻居个体。
; u+ [/ g' B4 ?移除状态(Remove,Refractory或者Recovered)。也成为免疫状态或恢复状态,当一个个体经历过一个完整的感染周期后,该个体就不再被感染,因此就可以不再考虑改革提。6 z' `# L$ `9 \$ z* v! N
SI传播模型是最简单的疾病传播模型,模型中的所有个体都只可能处于两个状态中的一个
( |: L( n: y. I) @8 ]% D即易感(S)状态或感染(I)状态。SI模型中的个体一旦被感染后就永远处于感染状态。
( }1 X, B/ p P, A在给定时刻t,令S(t)与I(t)分别代表该时刻处于易感和感染状态的个体数目,显然有
* e/ L! E( ?* P7 }# BS(t)+I(t)恒等于N,这里,N是个体总数。随着时间t的增长,易感个体与感染个体的接触- B- s+ i" V+ \3 O5 s' S+ P
会导致感染个体数量的增加。加入由于个体之间的接触而导致疾病传播的概率为β,疾病仅在
, ]6 ?4 @/ }% c# _ G: s' `1 N6 v感染个体和易感个体之间进行接触时才会以概率β将疾病传染给易感个体。在时刻t,易感个体的比例为S(t)/N,感染个体的数量为I(t),一次,易感个体的数量将以如下变化率减少
m% F- q. v) ^; Q3 K6 bds/dt = -β*S(t)I(t)/N) l+ k! ~, |# ^$ C$ U& Z3 G
同时,感染个体的数量会以与易感个体相反的变化率增加,
0 @, i. z6 I/ Z1 g$ u. `ds/dt = βS(t)*I(t)/N
: n1 v1 y6 C1 V& e4 S分别将时刻t处于易感状态和感染状态的个体所占比例记为,
9 ^) d! W" i. |& k; n# u9 Ns(t)=S(t)/N
" [0 @) T1 o8 s6 U0 o! ?7 Di(t)=I(t)/N7 ?! A+ z4 t% B
显然有,
, V/ `- P* Y, s0 D: ~4 h: s Vs(t)+i(t)恒等于1,此时之前的公式可以记做" f$ B% O& s% V% H
ds/dt=-βsi
9 _6 b! ^! y" o. i3 edi/dt=βsi
9 o& N; N8 C8 \8 e2 @即0 {1 D! f, |! V* }# d k' g
di/dt=βi(1-i): O9 J5 o1 w2 R& @. D. h: C
上式也成为Logistic增长方程式(Logistic growth equation),
9 W, D2 D U4 E: x) e: g# g( X方程的解和图像如图1 K' ]: L9 Z$ }
z5 `( x# }- _% |9 ?! D0 N代码和相关文件以及环境链接:链接:https://pan.baidu.com/s/1JSfHuTPaglFimeEBLdSDyQ/ O$ g6 `! U! I8 m$ z( J6 z1 j
提取码:z448
( B" \! F- ]: d, k- A' @" E5 ?- }7 y; p0 }, ?& L" K
, G$ A" R% B* G* x" D, d
'''& ?* |" L$ [* M# d1 k7 z
实验环境Python2.7.13,igraph包,cairo包,numpy包
- b# i; t9 o, R& j: s9 ^'''- i3 ]- i4 c' _2 R8 `
# -*- coding:utf8 -*
0 L$ Z0 F! X0 ~" t( |; c) |+ jfrom igraph import */ g; z. i& u# g$ \7 G' n
import numpy as numpy+ H' j0 l6 k& b+ f
from numpy import ** m/ l- O$ }$ v& _
import random
1 `1 s8 c% O# l2 v7 {* l/ s9 A
& D- I3 C& a0 T8 `def len_arr(infected_array,nodes_num):#获取感染数组长度
' J7 ^0 `# c) @5 A4 p4 d+ I) L. | len_value=0#初始化长度
+ b* ]/ P/ V/ L& M( n# L8 v7 L- E len_value=nodes_num-infected_array.count(-1)#被感染数量是结点总数减去未感染节点数(未感染的结点被标记为-1)8 ^9 n/ K% q5 v ]6 j" S5 x7 W
return len_value
G& C! N* K" T5 w8 V
. |6 N: e5 g6 v( l% `4 Gg=Graph.Read_GML("C:\python27\e1.gml")#将本地保存的网络数据读入变量g(生成图)3 n" W6 _" h; A+ s9 u( v+ p
summary(g)
1 }4 ]# x- \7 M: N* k9 Enodes_num=g.vcount()#统计图中的结点个数8 ^% }/ x- b, a2 e; Q6 W9 m
net_mat=g.get_adjacency(type=GET_ADJACENCY_BOTH)#将网络数据转换为邻接矩阵存储在变量net_mat- y# r, @# [ A8 c3 r
g.vs["color"]=["white"]#给图的顶点序列颜色赋值白色
4 o# z# Q+ Z' ea=[arange(nodes_num)+1]*3#声明一个N行3列的数组a, ]8 z3 r7 b& q
nodes_state=matrix(a).T#nodes_state通过转置a矩阵创建,用于存放每个节点的状态信息以及其被感染的时间(这个是理解算法的重中之重!!!)
; D$ m# m4 |1 b5 H" D; K9 l4 ~6 G #第一列是节点编号,第二列是节点状态,感染状态用-2表示,第三列是节点感染的时间( P# h3 m3 t" K, y; E
print(nodes_state)
8 ]0 G0 r9 {9 u. K' Uinfected_array=[-1]*34#用于存放本轮被感染的结点, 这些结点将参与下一次感染 34代表网络节点数/ h* K5 d) `6 J& n* b: T) z
print(infected_array)
+ J3 T* u. E0 e. g6 D j$ T4 _: ?7 q$ V4 c& `
infe_rate=1#传播率(感染率) 1代表邻接点100%被感染
- r. y0 p5 I3 m. X: c8 B9 S( L8 hset_time=2#传播次数(感染次数) 2次
/ @! q9 Y5 }- g& Q# m2 lsource_seed=1#感染源位置
4 v) l0 s7 C% s$ K! Mnodes_state[0:nodes_num,2]=-1#给所有节点初始化感染时间为-14 V6 w% X) C9 f" }- A9 c' _
nodes_state[source_seed-1,1]=-2#设置第一个感染源感染状态 -2代表感染状态
5 k0 k' v: a' y/ s% R6 _nodes_state[source_seed-1,2]=1#设置第一个感染源的感染时间为1
/ q* \: r q+ T2 t# Kg.vs[source_seed-1]["color"]="red"#将感染的顶点颜色标红( s8 I M& C$ W9 v1 f9 K0 K/ A! ~
infected_array[0]=source_seed#将感染源的位置存入被感染节点列表
# B' K& s) n. Z5 ]plot(g)#绘制% m: i6 D& v j$ K9 W
; F) y% e$ ~! tstop=False#感染过程结束的标记( ?# p* Z, B2 b C/ v, |
temp_time=0#第几次感染
0 q9 C: @" @+ J( ]7 ^' w7 k6 n5 ftemp_len=0#本轮的感染源数量初始化" T9 r) X. {3 z# t
' x! H! u4 A' ?! ?7 P
while not stop:5 g ^: s# `6 S- k
i=0#记录让每个感染源都传播一次
/ M8 c9 V# o! k7 R/ ? if len_arr(infected_array,nodes_num)>0 and len_arr(infected_array,nodes_num)<=nodes_num:#感染可以进行1 W9 u4 L$ V, f" [+ S
temp_len=len_arr(infected_array,nodes_num)#获取本轮的感染源数量 L4 W8 ^6 v: ?& K3 d) N
while i<temp_len:
- I5 a( o& y, N" o. g temp_time=nodes_state[infected_array-1,2]#获取每一个节点的感染时间
5 C8 l D: }! \: |: j( K! u nei_count=0#下一轮可以被感染到的节点数量9 T) }1 O$ n% i/ j
#生成下一轮可能被感染的节点的集合nei_arr
6 O' s+ g2 p+ c1 }5 U+ ~ for j in range(nodes_num):#遍历节点# s: q5 I6 X) b @6 t. Y
if net_mat[infected_array-1,j]==1 and nodes_state[j,1]!=-2:#是邻接节点而且未被感染, X# O: a4 A, R* F9 B+ d
nei_count=nei_count+1#下一轮可以被感染到的节点数量++& ~5 _& i) l: k8 X+ ]
nei_arr=[-1]*nei_count#用于临时存放本轮被感染的结点, 这些结点将参与下一次感染
& q) ^- y- _% E+ s# p k' q t=0
" x) R8 R4 A8 K& W. Q for j in range(nodes_num):* M: ?* I' v) ]& O# Y- A
if net_mat[infected_array-1,j]==1 and nodes_state[j,1]!=-2:( _+ c% F! T+ `. Q0 ?% v
nei_arr[t]=j+1
$ ~5 c! I! t2 J7 _2 u. Z$ U) H t=t+15 ]+ w4 g( v. O- w1 P' n3 J5 \6 `
ran_infe_arr=random.sample(range(nei_count),int(nei_count*infe_rate))#随机生成会被感染的节点的数组
/ H) B" h/ [* C* l #random.simple(arg1,num) 从arg1集合中随机取num个数据生成一个对象
) ?, v/ @/ |& i* H if len(ran_infe_arr)>0:#存在需要被感染的节点
( R4 r' Q1 z5 c% w) J t=0#让ran_infe_arr内每个感染源都被感染6 o2 l& R9 z B6 b$ O; i
while t<len(ran_infe_arr):#对刚才生成的会被感染的数组内的节点进行感染9 Z6 ?$ O. z1 t; D7 |8 B, r4 _
nodes_state[nei_arr[ran_infe_arr[t]]-1,1]=-2#标记为感染状态6 H0 h/ [* Z! p& D* [5 \
nodes_state[nei_arr[ran_infe_arr[t]]-1,2]=temp_time+1#记录感染时间8 h2 j. M8 @, G- I# c5 \
infected_array[len_arr(infected_array,nodes_num)]=nei_arr[ran_infe_arr[t]]#将此次感染节点放入总的感染节点数组中
6 w# n1 U }) G g.vs[nei_arr[ran_infe_arr[t]]-1]["color"]="pink"#将此次感染的节点集的所有节点颜色置为粉色9 T* Y7 q) A, u. g
plot(g)#绘制: s! A% x9 n% B. V6 k
t=t+1
3 H- ^" W) a' N0 z& K i=i+1
+ C% n& M; e5 e6 ^- @ if temp_time>set_time-1:#当执行感染的次数等于设置的次数结束感染
# _/ p4 y; G7 I# A) N! I& Y8 ` stop=True $ ~* m0 ]# u1 Z. n) U/ {& M* r8 O
) ~7 i9 n9 b% F6 {0 |
! b; T( c( {/ p5 q2 o" c+ G# p1 n+ f
视频演示bilibili传送门
8 ~ A# N# M: |/ x2 N/ F效果图
; r0 w7 v4 [$ z/ p1 m$ K* A. K2 l9 H
6 K) R) r- z% L
- Q( d' |' p% E* h; k: T* A
2 X8 V8 ]: E: m% ?# m
3 m- t% F4 c9 s
- w: s3 V' G9 V- s
! m- Y0 D" \( v7 Y4 Y
E. u, z2 @( U2 h6 M( y- X, H( F2 _3 D7 J
" ]: q, o3 e9 Z j, Y
; |& S0 r: X7 k: |+ _7 h: Y
, o* m" \% n" M8 n( L0 g# M. J( r7 c4 N$ @4 x
————————————————
% O/ n" ^! G- G/ Z版权声明:本文为CSDN博主「eck_燃」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
" J7 L! U* O0 z0 W& c原文链接:https://blog.csdn.net/wdays83892469/article/details/80878862
0 R7 y/ b& h) i n$ s6 n
) j0 | L& Q2 J" R
5 f7 t% a/ l" x# y |
zan
|