在线时间 1630 小时 最后登录 2024-1-29 注册时间 2017-5-16 听众数 82 收听数 1 能力 120 分 体力 566864 点 威望 12 点 阅读权限 255 积分 175282 相册 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传播模型 4 i h, Z: a9 W4 ]7 o
#SI疾病传播模型的原理
: z8 k$ Z8 `# G# }8 ^9 W 在经典的传染病模型中,种群(Population)内N个个体的状态可分为如下几类
+ L4 [' e2 Y) \8 A" d. h& I
; Q. G7 B: X- N/ A9 p" ~0 [2 z 易感状态(Susceptible)。一个个体在感染前是处于易感状态的,即该个体有可能被邻居个体感染。" A9 F. W. [5 L. Z
易感状态I(Infected)。一个感染上某种病毒的个体就称为是处于感染状态。,即该个体还会以一定概率感染其邻居个体。
' w% h, u' v. t- B% ~ 移除状态(Remove,Refractory或者Recovered)。也成为免疫状态或恢复状态,当一个个体经历过一个完整的感染周期后,该个体就不再被感染,因此就可以不再考虑改革提。
6 ~3 S4 y- d% H SI传播模型是最简单的疾病传播模型,模型中的所有个体都只可能处于两个状态中的一个
) C; X* { w7 L" } 即易感(S)状态或感染(I)状态。SI模型中的个体一旦被感染后就永远处于感染状态。
* O! T1 J+ P, r 在给定时刻t,令S(t)与I(t)分别代表该时刻处于易感和感染状态的个体数目,显然有
2 @" d$ I0 y1 s0 d2 I/ H8 k$ F S(t)+I(t)恒等于N,这里,N是个体总数。随着时间t的增长,易感个体与感染个体的接触; S3 v7 x9 B- u
会导致感染个体数量的增加。加入由于个体之间的接触而导致疾病传播的概率为β,疾病仅在! |" g3 A) s U% ^. N, m
感染个体和易感个体之间进行接触时才会以概率β将疾病传染给易感个体。在时刻t,易感个体的比例为S(t)/N,感染个体的数量为I(t),一次,易感个体的数量将以如下变化率减少. I9 M$ _0 j+ r/ U3 w
ds/dt = -β*S(t)I(t)/N; p2 a6 R# @/ ~; s4 M& P2 l+ w
同时,感染个体的数量会以与易感个体相反的变化率增加,
' o) ^- n; d9 a& [& ]- j A+ m" C ds/dt = βS(t)*I(t)/N N+ V" |$ I* R1 {
分别将时刻t处于易感状态和感染状态的个体所占比例记为,
$ x$ D, Z# N# | s(t)=S(t)/N0 X5 u; r7 o1 R% T: N" {: D0 Z: c
i(t)=I(t)/N
8 |1 l0 A0 |* e) } 显然有,- o' S, ?1 |# \. p' W- F
s(t)+i(t)恒等于1,此时之前的公式可以记做
* B1 h& ?) d( \2 }' i8 u$ u0 l ds/dt=-βsi
% G c9 J* W5 i5 z: {% U di/dt=βsi
3 h; s. W9 }8 }/ \7 `0 y 即" X3 ^6 f" e" c9 G) a7 i
di/dt=βi(1-i), F- m+ Q% T2 m2 C6 W9 k2 o
上式也成为Logistic增长方程式(Logistic growth equation),
2 B/ P1 h5 }+ J( h+ y( s4 q( }2 _% O 方程的解和图像如图
" f: B5 m2 v+ A. P2 T
& m6 _# L4 f# d {: C/ j* [
代码和相关文件以及环境链接:链接:https://pan.baidu.com/s/1JSfHuTPaglFimeEBLdSDyQ+ L- [ v% `3 o0 o! s L2 S( s+ E! p
提取码:z448- \: ?9 }% i: X5 R& C
" y O* s5 b6 }* u- i& [
% O5 D" m9 c$ \) F '''6 n/ i+ b$ e0 K/ z' O' X
实验环境Python2.7.13,igraph包,cairo包,numpy包% g/ E. o" ]% c4 w, r; |* S" p
'''
! h% y0 d2 l& h; P$ _ # -*- coding:utf8 -** F+ U! o' R( F$ \1 P8 K
from igraph import *4 ?% D+ h6 ?/ [9 }
import numpy as numpy, Z' z) h* t( H d
from numpy import *8 }$ P8 G6 H$ }9 y0 a+ b8 p: x4 H/ h
import random
. l4 M7 Z$ z+ A0 P( U
) ?7 k0 I. B% b0 C5 s def len_arr(infected_array,nodes_num):#获取感染数组长度
6 G, c4 [8 ^& z9 T+ D z5 y len_value=0#初始化长度
* k- w' u) E) `9 i len_value=nodes_num-infected_array.count(-1)#被感染数量是结点总数减去未感染节点数(未感染的结点被标记为-1)" w, A9 Z9 F: d0 ]( g, \
return len_value
; t8 M" }$ X/ v2 M r) d
: e0 ^$ `; W( @ @) {" M2 h, a g=Graph.Read_GML("C:\python27\e1.gml")#将本地保存的网络数据读入变量g(生成图)' s9 C. B% v4 @0 Z& \2 \
summary(g)# [ D% v& Q- @
nodes_num=g.vcount()#统计图中的结点个数. k1 j+ w# o4 R. T) J. I
net_mat=g.get_adjacency(type=GET_ADJACENCY_BOTH)#将网络数据转换为邻接矩阵存储在变量net_mat# f" n, c* G$ \# h
g.vs["color"]=["white"]#给图的顶点序列颜色赋值白色
7 i0 Z. b9 f5 B1 m; ~3 r1 ~ a=[arange(nodes_num)+1]*3#声明一个N行3列的数组a( v. U2 h6 t4 S% D3 q) y/ g; f* K
nodes_state=matrix(a).T#nodes_state通过转置a矩阵创建,用于存放每个节点的状态信息以及其被感染的时间(这个是理解算法的重中之重!!!)
5 y" w' _8 i( A( r4 V& \! c5 |$ ] #第一列是节点编号,第二列是节点状态,感染状态用-2表示,第三列是节点感染的时间: |: S$ M' [+ x) c1 G) C0 |2 z$ p g5 E
print(nodes_state)0 w3 L, m! H9 A1 I7 Z4 k5 j
infected_array=[-1]*34#用于存放本轮被感染的结点, 这些结点将参与下一次感染 34代表网络节点数
" T3 H3 D9 f7 F/ N* x% N$ T7 S print(infected_array)% C6 Z7 G1 V6 Z5 p3 c
& g9 e/ G" u: N infe_rate=1#传播率(感染率) 1代表邻接点100%被感染( @8 j8 ^) q; x& i
set_time=2#传播次数(感染次数) 2次% I, e8 }! o# E
source_seed=1#感染源位置
* e- O( ~4 ^& _# u4 r% W nodes_state[0:nodes_num,2]=-1#给所有节点初始化感染时间为-1
# ] [5 d2 K0 F. v nodes_state[source_seed-1,1]=-2#设置第一个感染源感染状态 -2代表感染状态- G! d$ G4 D6 x$ U
nodes_state[source_seed-1,2]=1#设置第一个感染源的感染时间为1- W, L1 }. v0 w: z. Z" Q. x
g.vs[source_seed-1]["color"]="red"#将感染的顶点颜色标红! Z7 A6 L2 s$ n6 l+ \
infected_array[0]=source_seed#将感染源的位置存入被感染节点列表9 r- U+ E) p" F8 f0 w
plot(g)#绘制
- Z. p) X8 C5 E - ~2 e6 A. x5 h4 E
stop=False#感染过程结束的标记
! I. w( Z$ H" Q) \1 h' C temp_time=0#第几次感染; K+ f! B" |* [' O- {
temp_len=0#本轮的感染源数量初始化
" `# w0 Y7 V) [( ^, y3 l$ {: ` % Q/ v# `- v2 G! m* w' e
while not stop:
9 m6 s9 m V2 g' \ i=0#记录让每个感染源都传播一次0 h3 d' i+ b4 I( M
if len_arr(infected_array,nodes_num)>0 and len_arr(infected_array,nodes_num)<=nodes_num:#感染可以进行
, J/ G/ y5 G0 i7 m& j temp_len=len_arr(infected_array,nodes_num)#获取本轮的感染源数量
; M: A ]: o' d1 ] while i<temp_len:
8 {6 [1 t+ N! W+ e; O temp_time=nodes_state[infected_array-1,2]#获取每一个节点的感染时间
, i" F6 E! c' l4 e# v nei_count=0#下一轮可以被感染到的节点数量; i$ m; [) R3 h" y+ O! F
#生成下一轮可能被感染的节点的集合nei_arr0 K7 \$ P9 G w8 O# |
for j in range(nodes_num):#遍历节点- U" P) q$ v {! l
if net_mat[infected_array-1,j]==1 and nodes_state[j,1]!=-2:#是邻接节点而且未被感染
: y I9 b) R) z8 n e$ A, g2 l nei_count=nei_count+1#下一轮可以被感染到的节点数量++
2 [2 q( }. A+ T6 Y0 r) a nei_arr=[-1]*nei_count#用于临时存放本轮被感染的结点, 这些结点将参与下一次感染4 r; G+ X2 F, H9 u
t=05 c6 L9 G4 Q5 p1 K8 [. d' t' X
for j in range(nodes_num):, h0 C! @, p; y2 q1 W4 u- p& U
if net_mat[infected_array-1,j]==1 and nodes_state[j,1]!=-2:
# |" z) `; m# S) Y* V: D0 M1 o! ~ nei_arr[t]=j+1
9 _& |9 Y. f, I1 G2 \* E7 b t=t+1
9 i9 x8 V9 F3 v" m5 m ran_infe_arr=random.sample(range(nei_count),int(nei_count*infe_rate))#随机生成会被感染的节点的数组3 y% z X4 Z' ]! Q
#random.simple(arg1,num) 从arg1集合中随机取num个数据生成一个对象& {- ?0 ^7 u# n, H6 s
if len(ran_infe_arr)>0:#存在需要被感染的节点" @- ^6 C, U9 n, C
t=0#让ran_infe_arr内每个感染源都被感染' O& @& H. q; ^/ N+ q
while t<len(ran_infe_arr):#对刚才生成的会被感染的数组内的节点进行感染
1 }8 d' D$ ]6 }& f) Z8 @ nodes_state[nei_arr[ran_infe_arr[t]]-1,1]=-2#标记为感染状态6 _( A' e, b/ S/ ~
nodes_state[nei_arr[ran_infe_arr[t]]-1,2]=temp_time+1#记录感染时间7 ]) M& }0 h% Y9 M& Y
infected_array[len_arr(infected_array,nodes_num)]=nei_arr[ran_infe_arr[t]]#将此次感染节点放入总的感染节点数组中
3 b; o/ o% x( i9 L' h- ?" K9 B g.vs[nei_arr[ran_infe_arr[t]]-1]["color"]="pink"#将此次感染的节点集的所有节点颜色置为粉色9 U# u# U4 E* k' t9 {
plot(g)#绘制
- n l7 P, z# ]+ d- G2 Q t=t+1* p; P& E4 Y }4 x- \; j! V* T1 m
i=i+1
% d8 I4 b9 E' A% Q a: @' R1 x( Q if temp_time>set_time-1:#当执行感染的次数等于设置的次数结束感染
. }8 n; z, a! h; ]! ~% w7 C8 } stop=True * S* Z9 `% h& f8 s: X7 O
, X/ k7 y5 E( V2 |8 i' [ 9 {* p' b3 p0 p1 w* P. @, t- w/ D7 \
视频演示bilibili传送门1 X5 D$ G1 w! ?: [( s5 J" A+ h7 H
效果图/ i! ?7 L" N' ^( y, g1 u7 k
: R, ^4 c1 u& p; C* i. }$ ? ) G; Y1 z: F4 C3 ?5 l' t. F4 r5 e- r+ @
- n, L0 ?+ m1 ?/ T 7 L8 b) ^: a3 P( B
% j% q9 m8 [, f, N1 w# E% B ( {5 i; w1 S0 j% S: V+ {
; |2 K+ H% T2 S 8 t/ h( d5 l! M7 D
. r( T9 s1 q6 S* e' r % n: c8 l7 s+ e& B. Y
) O2 H0 e/ G* O# |: U* _2 ?* ^
5 d: D4 L4 _1 w/ W
————————————————& F' X; T4 L* b! i3 F1 P( R
版权声明:本文为CSDN博主「eck_燃」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
( c5 O# J. I/ G U$ y) W% ^ 原文链接:https://blog.csdn.net/wdays83892469/article/details/808788622 e& Q. v/ c b
M0 v6 M7 B! f* ^; `' J' P h& z- i" W
+ Q H1 `% k' K- P
zan