QQ登录

只需要一步,快速开始

 注册地址  找回密码
查看: 3118|回复: 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传播模型& D* z6 p5 P9 z5 \
    #SI疾病传播模型的原理
    6 I% H: Q% X( M8 u( V& F在经典的传染病模型中,种群(Population)内N个个体的状态可分为如下几类
    # M* z* \$ @3 s" f) ~( b/ {# E( N
    " w' O2 A) U1 l0 {. J& b3 X+ r! y易感状态(Susceptible)。一个个体在感染前是处于易感状态的,即该个体有可能被邻居个体感染。$ g( Y. b6 k- K, M
    易感状态I(Infected)。一个感染上某种病毒的个体就称为是处于感染状态。,即该个体还会以一定概率感染其邻居个体。  {3 s' [3 t% w1 A6 A, l
    移除状态(Remove,Refractory或者Recovered)。也成为免疫状态或恢复状态,当一个个体经历过一个完整的感染周期后,该个体就不再被感染,因此就可以不再考虑改革提。: z$ Z8 _) D. Z6 N# G
    SI传播模型是最简单的疾病传播模型,模型中的所有个体都只可能处于两个状态中的一个
    - k# j4 \5 C( a- D6 U即易感(S)状态或感染(I)状态。SI模型中的个体一旦被感染后就永远处于感染状态。
    & L+ k# L5 q% X1 _' |0 ?. |1 n在给定时刻t,令S(t)与I(t)分别代表该时刻处于易感和感染状态的个体数目,显然有
    0 F; N0 y* d  M6 ]" ?/ mS(t)+I(t)恒等于N,这里,N是个体总数。随着时间t的增长,易感个体与感染个体的接触6 y1 Z3 |4 D" s, N) M  \
    会导致感染个体数量的增加。加入由于个体之间的接触而导致疾病传播的概率为β,疾病仅在* U) J5 X. ^& l  |6 Z5 e
    感染个体和易感个体之间进行接触时才会以概率β将疾病传染给易感个体。在时刻t,易感个体的比例为S(t)/N,感染个体的数量为I(t),一次,易感个体的数量将以如下变化率减少
    $ ~6 P5 V7 S# |) j# v+ fds/dt = -β*S(t)I(t)/N+ w. c! A9 P' O6 p
    同时,感染个体的数量会以与易感个体相反的变化率增加,
    * ^7 K/ b) C: J6 Xds/dt = βS(t)*I(t)/N
    7 ?- E, w6 c5 ?0 J9 m- k6 F" l7 C分别将时刻t处于易感状态和感染状态的个体所占比例记为,, @5 F3 O* f+ R0 p$ R
    s(t)=S(t)/N% R1 ]6 z2 Y. \* W% K6 }. n2 t: E
    i(t)=I(t)/N' }+ z4 c* o1 @! [6 V
    显然有,  M# I2 B* Y2 W: \
    s(t)+i(t)恒等于1,此时之前的公式可以记做
    3 ~/ [: d, e* Vds/dt=-βsi
    0 N+ X: i) d" `di/dt=βsi0 s: k2 O2 ^6 T' l

    ) y3 \. s5 w3 Gdi/dt=βi(1-i); R( ~9 a6 @- V3 A, Z6 S$ P; }$ s
    上式也成为Logistic增长方程式(Logistic growth equation),) ^. q! M. ]* r5 e( R9 W
    方程的解和图像如图
    " ^, [( W0 B$ H6 J) l, H& J 1.jpg 3 v: c3 q7 M' y5 I: y# K. o+ o
    代码和相关文件以及环境链接:链接:https://pan.baidu.com/s/1JSfHuTPaglFimeEBLdSDyQ
    , ]' H" T7 \# O, @/ o9 a% T提取码:z448% z0 ^. h0 w3 K4 B& Q  I

    * z3 Z2 v9 O, c0 P8 ~7 w% ]2 n  f
    '''5 K  C; ?- y9 e/ h# E
    实验环境Python2.7.13,igraph包,cairo包,numpy包4 ~) V$ k2 n2 i$ O+ N1 z
    '''8 D3 N) y* Q/ z& V- a
    # -*- coding:utf8 -*; e( }' s# n6 F8 [, c  T, k  e+ v- n* N: B
    from igraph import *
    # b: L  b6 l* \9 uimport numpy as numpy' z, l* i. m# Y4 U$ J
    from  numpy import *
      n$ J0 k4 @+ O& Cimport random3 l  I; J* g/ H3 u, r1 F+ ?
    % E" R; n3 @% l6 [; ~' A5 p
    def len_arr(infected_array,nodes_num):#获取感染数组长度' \/ y: e! v7 C3 w  u: x1 v$ K
        len_value=0#初始化长度7 p* v# l% d% f  X
        len_value=nodes_num-infected_array.count(-1)#被感染数量是结点总数减去未感染节点数(未感染的结点被标记为-1)
    + ~9 D) A7 M$ n    return len_value
    1 F, g: g' s/ w) {, m4 u
    4 T# P$ p; h7 a6 `$ ag=Graph.Read_GML("C:\python27\e1.gml")#将本地保存的网络数据读入变量g(生成图)8 v' m$ s& ?) t
    summary(g)) M8 X3 G2 m) b
    nodes_num=g.vcount()#统计图中的结点个数
    - F% t! l: r" w8 j( Onet_mat=g.get_adjacency(type=GET_ADJACENCY_BOTH)#将网络数据转换为邻接矩阵存储在变量net_mat
    ) K3 o5 n1 D  t5 Xg.vs["color"]=["white"]#给图的顶点序列颜色赋值白色
    + ~/ }+ _' c* {& j# E9 _& k/ V( e* \, `a=[arange(nodes_num)+1]*3#声明一个N行3列的数组a
    4 f. l$ a( v* A& m) Hnodes_state=matrix(a).T#nodes_state通过转置a矩阵创建,用于存放每个节点的状态信息以及其被感染的时间(这个是理解算法的重中之重!!!)
    6 p' Y5 l" v- k0 D2 r0 e                                                    #第一列是节点编号,第二列是节点状态,感染状态用-2表示,第三列是节点感染的时间; r8 k/ I& M: O7 _+ V2 T: Y
    print(nodes_state)# j( H- m* r1 w- E. V
    infected_array=[-1]*34#用于存放本轮被感染的结点, 这些结点将参与下一次感染   34代表网络节点数
    . V$ r& k1 v8 B6 b( Pprint(infected_array)9 W+ j7 K* ~3 j) h/ H- b6 d( k2 p% \; Y

    . r( j5 k* V2 M$ [, G. U, Qinfe_rate=1#传播率(感染率) 1代表邻接点100%被感染8 F, w9 q4 u! J, H( m* r
    set_time=2#传播次数(感染次数) 2次
    9 ~" W( c5 M* ]( {" S! ^source_seed=1#感染源位置
    % q$ w  Z  z) n  Onodes_state[0:nodes_num,2]=-1#给所有节点初始化感染时间为-1$ ~9 Y, O. v9 P; C4 v  i
    nodes_state[source_seed-1,1]=-2#设置第一个感染源感染状态 -2代表感染状态
    1 I; a# ~! k+ W) znodes_state[source_seed-1,2]=1#设置第一个感染源的感染时间为1  n; u7 W- O5 V; p4 |. ?
    g.vs[source_seed-1]["color"]="red"#将感染的顶点颜色标红
    ! C0 a' t  y3 ^7 b" b/ C& ^infected_array[0]=source_seed#将感染源的位置存入被感染节点列表% @2 y/ b) K: t
    plot(g)#绘制
    * r, {0 S9 |0 G9 v* X
    % [0 }4 n" r* h; o( N  mstop=False#感染过程结束的标记- i; `7 c$ \3 c1 l$ T) {
    temp_time=0#第几次感染
    : T8 |" Q3 R% ~) @1 Vtemp_len=0#本轮的感染源数量初始化
    3 V7 Q$ v& p3 P- t" l" g; n$ L, }: x2 a7 n
    while not stop:
    # f' i3 P. Y) ?. V* ~    i=0#记录让每个感染源都传播一次5 \; e5 `$ D0 u4 w9 m# ^5 F
        if len_arr(infected_array,nodes_num)>0 and len_arr(infected_array,nodes_num)<=nodes_num:#感染可以进行
    ! l' n& Q: @- \! r- K" d        temp_len=len_arr(infected_array,nodes_num)#获取本轮的感染源数量
    & z# `' y, ?. C; i( H0 y8 _9 _        while i<temp_len:4 d5 u* O4 G- w( _4 _
                temp_time=nodes_state[infected_array-1,2]#获取每一个节点的感染时间7 |& q- I/ f& K% s8 \. \
                nei_count=0#下一轮可以被感染到的节点数量
    ( E6 a- ~8 \  u4 k. u            #生成下一轮可能被感染的节点的集合nei_arr3 i5 E* w  ?& |% z$ V! g/ V
                for j in range(nodes_num):#遍历节点5 @2 {: N3 [4 Z& p% w1 n
                    if net_mat[infected_array-1,j]==1 and nodes_state[j,1]!=-2:#是邻接节点而且未被感染
    1 L2 E: F/ X. e) k- Q' e1 ^                    nei_count=nei_count+1#下一轮可以被感染到的节点数量++1 F. G" s0 j$ H' a
                nei_arr=[-1]*nei_count#用于临时存放本轮被感染的结点, 这些结点将参与下一次感染' T. v2 o- g  K, \: q3 _
                t=0
    & w2 d, C  O& P6 b3 c            for j in range(nodes_num):
    & h( o; E  [" N2 Q! P* e                if net_mat[infected_array-1,j]==1 and nodes_state[j,1]!=-2:0 i6 e% ^6 b$ ]: i
                        nei_arr[t]=j+1! n0 u- B4 s; _& U3 g
                        t=t+1
    $ M: Q7 G( {/ B$ R* `            ran_infe_arr=random.sample(range(nei_count),int(nei_count*infe_rate))#随机生成会被感染的节点的数组
    3 X9 c+ _7 Q, @/ y                                        #random.simple(arg1,num) 从arg1集合中随机取num个数据生成一个对象3 C9 b! G# \# D$ j. m
                if len(ran_infe_arr)>0:#存在需要被感染的节点
    9 t4 ^) j) J/ e' x# B                t=0#让ran_infe_arr内每个感染源都被感染
    & ?5 P  q* i5 E. G5 g                while t<len(ran_infe_arr):#对刚才生成的会被感染的数组内的节点进行感染/ s+ b& ~) W7 m9 M# f
                        nodes_state[nei_arr[ran_infe_arr[t]]-1,1]=-2#标记为感染状态6 {6 L, b6 W1 r$ U8 W5 c; J2 B
                        nodes_state[nei_arr[ran_infe_arr[t]]-1,2]=temp_time+1#记录感染时间
    - x/ ~+ ^: B8 a$ m  P; r  Z5 ~                    infected_array[len_arr(infected_array,nodes_num)]=nei_arr[ran_infe_arr[t]]#将此次感染节点放入总的感染节点数组中' ^2 \$ A+ g! s+ @! G" U( z) F
                        g.vs[nei_arr[ran_infe_arr[t]]-1]["color"]="pink"#将此次感染的节点集的所有节点颜色置为粉色# N! l2 V3 M/ f. U& J
                        plot(g)#绘制
    + [3 T, o& {2 ~8 W! B                    t=t+1; J& o. u/ l7 H% Y) z' U
                i=i+1
    / l4 y. p2 K  B. E    if temp_time>set_time-1:#当执行感染的次数等于设置的次数结束感染5 Q; n& [) u5 a7 V: G  S' X8 p2 y
            stop=True
    7 l/ z5 M" q- z& u: K2 W9 J0 m( f. \# @
    ' R. k; U  C, r0 @. B
    视频演示bilibili传送门5 \7 b) R4 d5 k% R
    效果图+ Y2 p3 V- J7 |( U

    ' g1 y6 {+ p8 Q% f7 K' t; i0 m4 N) Y. U; K& i! O
    2.jpg
    9 y2 z+ `5 J- r" Q& Y+ ?0 ^& t3 B; `
    3.png * O4 a, G8 u! J) {( d

    # y  z0 r( V! @0 S+ Y 4.jpg ( ^9 H# t* T* @: {( n# e

    # i. q+ c' m. u- ?( x 5.png ' K! [" F5 n8 z$ W6 d1 f  \
    " B' H" b0 h, v' z
    6.png 7 m' O- o+ J, N9 U& ^& F0 _
    ) s4 V8 i4 A4 p& n0 z
    7.png ————————————————/ q$ z' L2 f4 ?! G6 N* \! T
    版权声明:本文为CSDN博主「eck_燃」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。' q$ y7 M) ?1 O
    原文链接:https://blog.csdn.net/wdays83892469/article/details/80878862
    1 c  D" C" n4 J( ]7 j* E: z; n8 c9 g6 j3 L2 y

    ) ]' B3 P3 |6 b0 b' P, L/ y
    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-7-26 00:03 , Processed in 0.622293 second(s), 58 queries .

    回顶部