QQ登录

只需要一步,快速开始

 注册地址  找回密码
查看: 3102|回复: 1
打印 上一主题 下一主题

Python实现简单的SI传播模型

[复制链接]
字体大小: 正常 放大
杨利霞        

5273

主题

82

听众

17万

积分

  • TA的每日心情
    开心
    2021-8-11 17:59
  • 签到天数: 17 天

    [LV.4]偶尔看看III

    网络挑战赛参赛者

    网络挑战赛参赛者

    自我介绍
    本人女,毕业于内蒙古科技大学,担任文职专业,毕业专业英语。

    群组2018美赛大象算法课程

    群组2018美赛护航培训课程

    群组2019年 数学中国站长建

    群组2019年数据分析师课程

    群组2018年大象老师国赛优

    跳转到指定楼层
    1#
    发表于 2020-4-18 16:16 |只看该作者 |倒序浏览
    |招呼Ta 关注Ta
    Python实现简单的SI传播模型. Z: y; s5 T0 K0 I+ x! T. y& a
    #SI疾病传播模型的原理
    - \) U! x; p; Q6 `7 p4 Q. u在经典的传染病模型中,种群(Population)内N个个体的状态可分为如下几类' \* F8 x  _6 ]
    4 m9 ?  }9 Q: G4 a/ ~
    易感状态(Susceptible)。一个个体在感染前是处于易感状态的,即该个体有可能被邻居个体感染。% v8 }3 k, j0 m. [, h* w" a
    易感状态I(Infected)。一个感染上某种病毒的个体就称为是处于感染状态。,即该个体还会以一定概率感染其邻居个体。' L- O2 z& H- n7 S
    移除状态(Remove,Refractory或者Recovered)。也成为免疫状态或恢复状态,当一个个体经历过一个完整的感染周期后,该个体就不再被感染,因此就可以不再考虑改革提。9 }+ M5 U9 d8 R' f" b) v" ]
    SI传播模型是最简单的疾病传播模型,模型中的所有个体都只可能处于两个状态中的一个
    ) O( ?# F# K7 @" z; _即易感(S)状态或感染(I)状态。SI模型中的个体一旦被感染后就永远处于感染状态。2 W, V# N9 [  a
    在给定时刻t,令S(t)与I(t)分别代表该时刻处于易感和感染状态的个体数目,显然有
    4 V, M# O( ]& J& mS(t)+I(t)恒等于N,这里,N是个体总数。随着时间t的增长,易感个体与感染个体的接触- O: F% a+ s4 ]  J' w3 P9 _+ T
    会导致感染个体数量的增加。加入由于个体之间的接触而导致疾病传播的概率为β,疾病仅在
    ( s% u1 X9 @7 `5 a1 n$ m* M# _感染个体和易感个体之间进行接触时才会以概率β将疾病传染给易感个体。在时刻t,易感个体的比例为S(t)/N,感染个体的数量为I(t),一次,易感个体的数量将以如下变化率减少
    ! i( W7 X7 J, ~- |5 [: j! b% H  @( zds/dt = -β*S(t)I(t)/N" x$ L+ F( `0 _; \
    同时,感染个体的数量会以与易感个体相反的变化率增加,9 y3 s1 P0 {1 c3 K' v
    ds/dt = βS(t)*I(t)/N8 o) V$ k. u: g9 k
    分别将时刻t处于易感状态和感染状态的个体所占比例记为,
    0 w$ q8 M- p  C+ p# M0 \s(t)=S(t)/N
    " M; w7 y+ V1 x4 Li(t)=I(t)/N' j# Z4 _* S  h: Y$ j9 I. O/ H
    显然有,
    ) T" y* h  u$ a9 s! f: Js(t)+i(t)恒等于1,此时之前的公式可以记做
      D5 l1 y# v7 {4 [& b3 `ds/dt=-βsi( r2 ~- a1 `' D2 X
    di/dt=βsi
    # j+ t' e* y6 ]8 m( B5 }; I
    1 ~' Z% N: o* N: m  qdi/dt=βi(1-i)
    % O. K: x% i: L2 ?6 Z. p9 {( }2 B上式也成为Logistic增长方程式(Logistic growth equation)," |2 t: a/ Y' A; E, t% P3 ]* E, p
    方程的解和图像如图
      t, G' Q$ K- e- O 1.jpg ( ^0 ?  O4 e7 c$ A. A
    代码和相关文件以及环境链接:链接:https://pan.baidu.com/s/1JSfHuTPaglFimeEBLdSDyQ
    , w; Y: F' N! k: [3 g3 l% @提取码:z448. c  S  S$ ?& n+ A7 x7 u* u% ?; d
    / n2 }. r7 g& ~9 t0 Q$ x, |% r
    3 U; E3 V! X7 \! w
    '''
    " t# F; L& G& i% q, ?7 ]实验环境Python2.7.13,igraph包,cairo包,numpy包
    ) }9 n9 n+ O8 }'''
      ?7 i  m1 ]8 D! O# -*- coding:utf8 -*
    5 ~" w1 g2 {: Ifrom igraph import *% M% Q$ j0 a* |$ r( r
    import numpy as numpy
    0 q" q: m  e2 q$ Z. X0 z  Kfrom  numpy import *
      v4 @5 d. u4 _  Zimport random
    & {) m3 R* m+ t6 a) o+ o/ J. D" o* W$ t! H& N9 s/ y
    def len_arr(infected_array,nodes_num):#获取感染数组长度
    % J: }* r8 [. n9 `. q7 x    len_value=0#初始化长度* J' X7 s+ _* I7 D
        len_value=nodes_num-infected_array.count(-1)#被感染数量是结点总数减去未感染节点数(未感染的结点被标记为-1): J2 s  y( A7 J5 J4 j
        return len_value' b  ?, c. G4 c

    ) F% z4 N0 ~/ H& v' q! j" bg=Graph.Read_GML("C:\python27\e1.gml")#将本地保存的网络数据读入变量g(生成图)
    5 x2 I8 q/ Z" c4 s2 B3 h5 u6 A. vsummary(g)
    6 i% n* f0 }2 t1 g1 Znodes_num=g.vcount()#统计图中的结点个数
    ( [: O0 N% n) [. V7 x& e) Unet_mat=g.get_adjacency(type=GET_ADJACENCY_BOTH)#将网络数据转换为邻接矩阵存储在变量net_mat! _) [( I4 G3 r
    g.vs["color"]=["white"]#给图的顶点序列颜色赋值白色' p, n) ?! N2 ^/ v1 z
    a=[arange(nodes_num)+1]*3#声明一个N行3列的数组a4 V$ S4 s1 S* ]  r5 ^) ?
    nodes_state=matrix(a).T#nodes_state通过转置a矩阵创建,用于存放每个节点的状态信息以及其被感染的时间(这个是理解算法的重中之重!!!)0 h, ^5 _+ M! c0 b; i7 R6 q
                                                        #第一列是节点编号,第二列是节点状态,感染状态用-2表示,第三列是节点感染的时间
    5 L4 u% F5 Z* }( Lprint(nodes_state)
    , _+ R) a* Q# q: Q; L2 }infected_array=[-1]*34#用于存放本轮被感染的结点, 这些结点将参与下一次感染   34代表网络节点数. l, R7 V5 C0 e9 `
    print(infected_array)
    % U. D5 j- ?- R6 h  E( a
    : Q+ b) i. T( h1 I8 d* }: F' i' Pinfe_rate=1#传播率(感染率) 1代表邻接点100%被感染
    4 e! N8 @9 _7 A, P  |' Zset_time=2#传播次数(感染次数) 2次4 E/ M$ o. ^7 f9 ^- _
    source_seed=1#感染源位置
    - l2 B, R* n  u! L  [nodes_state[0:nodes_num,2]=-1#给所有节点初始化感染时间为-1
    9 h& i0 z; B' T+ |, w9 \0 }nodes_state[source_seed-1,1]=-2#设置第一个感染源感染状态 -2代表感染状态8 t6 ]" Y& b3 Q! {  Y- x& R2 x
    nodes_state[source_seed-1,2]=1#设置第一个感染源的感染时间为1
    / T: n* n2 |" ig.vs[source_seed-1]["color"]="red"#将感染的顶点颜色标红5 r% ^, k# z& P) f5 `$ |) D& {
    infected_array[0]=source_seed#将感染源的位置存入被感染节点列表8 Z5 ]' E) W- ~3 V8 x: S  u; F
    plot(g)#绘制, W; G$ o6 ^+ U% N( I

    / q( }- Z- L& q+ b) v* `stop=False#感染过程结束的标记
    5 M" h. ]2 b# T8 a& k3 y1 h- m0 Ttemp_time=0#第几次感染
    ! F9 L0 M+ T' s7 X4 h- mtemp_len=0#本轮的感染源数量初始化
    8 R" I% j! F* O9 t$ P) m0 R$ U; H* @3 B1 p
    while not stop:
    5 o% t. g- T0 R( N8 x8 d+ H    i=0#记录让每个感染源都传播一次
    6 f1 l/ {( K$ D- U# c) D7 F+ H    if len_arr(infected_array,nodes_num)>0 and len_arr(infected_array,nodes_num)<=nodes_num:#感染可以进行3 y# y) [0 `+ U  Q. s* A( B# e3 l7 m' L
            temp_len=len_arr(infected_array,nodes_num)#获取本轮的感染源数量) J& j1 p$ d/ j! C
            while i<temp_len:
    . l4 ?- R7 v2 F' B/ t+ {            temp_time=nodes_state[infected_array-1,2]#获取每一个节点的感染时间
    2 v7 B$ ?) I" K) [4 g' x7 v& c            nei_count=0#下一轮可以被感染到的节点数量7 N# }% }9 b" Y
                #生成下一轮可能被感染的节点的集合nei_arr
    9 ?" T5 P- I& |& e6 B5 y            for j in range(nodes_num):#遍历节点
    / U! G0 n6 F+ U) S3 i5 S                if net_mat[infected_array-1,j]==1 and nodes_state[j,1]!=-2:#是邻接节点而且未被感染
    * i1 J9 Z+ L( F                    nei_count=nei_count+1#下一轮可以被感染到的节点数量++
    . d  h8 q( A3 y) z& Q            nei_arr=[-1]*nei_count#用于临时存放本轮被感染的结点, 这些结点将参与下一次感染5 z% _* Q/ r4 G6 O) Q5 X9 K- L& C( I
                t=0, A) o6 k! o7 W3 h# k2 c
                for j in range(nodes_num):" N% ^. H7 k8 z/ a* G) C" r* x
                    if net_mat[infected_array-1,j]==1 and nodes_state[j,1]!=-2:" _* {! c( X1 ]0 c1 N8 h
                        nei_arr[t]=j+1
    ! C% v( w/ z' j9 a+ a                    t=t+13 j' J4 b8 _* ?- \0 j
                ran_infe_arr=random.sample(range(nei_count),int(nei_count*infe_rate))#随机生成会被感染的节点的数组
    # @# H* w- v* J+ Y                                        #random.simple(arg1,num) 从arg1集合中随机取num个数据生成一个对象
    ' [- w* j1 }3 |  H: @            if len(ran_infe_arr)>0:#存在需要被感染的节点
    . R5 d1 b6 L) U6 o                t=0#让ran_infe_arr内每个感染源都被感染# {# D+ ?5 y6 l
                    while t<len(ran_infe_arr):#对刚才生成的会被感染的数组内的节点进行感染, K$ w; N2 i( U% f
                        nodes_state[nei_arr[ran_infe_arr[t]]-1,1]=-2#标记为感染状态
    2 b# f4 y+ d: q) D+ k                    nodes_state[nei_arr[ran_infe_arr[t]]-1,2]=temp_time+1#记录感染时间
    2 U. U. o* F) J                    infected_array[len_arr(infected_array,nodes_num)]=nei_arr[ran_infe_arr[t]]#将此次感染节点放入总的感染节点数组中
    8 d3 T# v; D; a" V  A                    g.vs[nei_arr[ran_infe_arr[t]]-1]["color"]="pink"#将此次感染的节点集的所有节点颜色置为粉色
    ; i7 i' l3 q- Y9 t8 ]3 l7 A                    plot(g)#绘制
    - h6 X" ?  @8 E0 b; M4 U& k" a                    t=t+1
    4 o' [  \1 Y$ K/ e2 L& g            i=i+1
      P- W9 m2 s2 R; R# _    if temp_time>set_time-1:#当执行感染的次数等于设置的次数结束感染
    / z3 a# e, L" K- X! J" A        stop=True / T6 C2 a+ R6 {
    4 R9 V+ [0 S$ d* a3 v6 n' f
    3 `: d; |2 ?$ q8 b$ o. @% k$ i
    视频演示bilibili传送门+ d# T* s/ [4 C8 j* v
    效果图
    % W# w' X. p3 `: a! t' c3 r
    8 B9 R; W9 W( E) b" X# |* c3 g, U4 z& M# |& P6 @
    2.jpg
    4 `2 R) C# A# |% h0 s0 b% m! [( G3 q
    3.png : P3 J0 g! q2 M, G+ ?0 I$ a

    1 `2 z" i; n$ }7 \: B& c  G 4.jpg ' {$ ^7 X  [& E

    ! [- O0 u+ M3 u& m/ A 5.png
    / S6 P; x) h- x
    ! G2 _: f* M" o: H% e% r 6.png
      x  }$ m+ v! Z; v7 O
    . n- p2 r+ ^: p 7.png ————————————————
    7 C" @, N7 W- R; j' A+ U! Y版权声明:本文为CSDN博主「eck_燃」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。3 K4 ~7 Z, a4 z' h! S" m: W+ h7 w
    原文链接:https://blog.csdn.net/wdays83892469/article/details/80878862
    % o" B7 K/ O& D: ]! C) L' z9 Y; e' p0 a4 c7 c( j4 [+ J: W
    + X) z! ]* h# Y" x8 A, a  _  I5 X
    zan
    转播转播0 分享淘帖0 分享分享0 收藏收藏0 支持支持0 反对反对0 微信微信
    尔雅 实名认证       

    0

    主题

    1

    听众

    208

    积分

    升级  54%

  • TA的每日心情
    开心
    2022-2-18 09:12
  • 签到天数: 17 天

    [LV.4]偶尔看看III

    网络挑战赛参赛者

    国际赛参赛者

    回复

    使用道具 举报

    您需要登录后才可以回帖 登录 | 注册地址

    qq
    收缩
    • 电话咨询

    • 04714969085
    fastpost

    关于我们| 联系我们| 诚征英才| 对外合作| 产品服务| QQ

    手机版|Archiver| |繁體中文 手机客户端  

    蒙公网安备 15010502000194号

    Powered by Discuz! X2.5   © 2001-2013 数学建模网-数学中国 ( 蒙ICP备14002410号-3 蒙BBS备-0002号 )     论坛法律顾问:王兆丰

    GMT+8, 2026-6-12 03:34 , Processed in 0.451030 second(s), 59 queries .

    回顶部