QQ登录

只需要一步,快速开始

 注册地址  找回密码
查看: 3064|回复: 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传播模型8 n6 E0 }' C$ q& Q; v, m
    #SI疾病传播模型的原理
    ) J8 P' ~+ u( `, a9 Z1 c在经典的传染病模型中,种群(Population)内N个个体的状态可分为如下几类
    : L) N2 A6 P8 }' e" T+ \4 ]5 M* s6 b
    易感状态(Susceptible)。一个个体在感染前是处于易感状态的,即该个体有可能被邻居个体感染。# p0 J1 r' F" N% n) C/ w5 e
    易感状态I(Infected)。一个感染上某种病毒的个体就称为是处于感染状态。,即该个体还会以一定概率感染其邻居个体。- s. {) D) @; f3 e
    移除状态(Remove,Refractory或者Recovered)。也成为免疫状态或恢复状态,当一个个体经历过一个完整的感染周期后,该个体就不再被感染,因此就可以不再考虑改革提。
    ! g0 P$ R3 D: e& z2 o- ~: W1 RSI传播模型是最简单的疾病传播模型,模型中的所有个体都只可能处于两个状态中的一个
    8 T) p2 r- y: |即易感(S)状态或感染(I)状态。SI模型中的个体一旦被感染后就永远处于感染状态。
    1 h" A  W* h$ L( c在给定时刻t,令S(t)与I(t)分别代表该时刻处于易感和感染状态的个体数目,显然有$ U/ b% z) J& P7 v+ @% q
    S(t)+I(t)恒等于N,这里,N是个体总数。随着时间t的增长,易感个体与感染个体的接触
    0 Y( e/ g3 i; g- ], @会导致感染个体数量的增加。加入由于个体之间的接触而导致疾病传播的概率为β,疾病仅在
    4 ^: }3 @! _7 m# P9 B8 ^$ V感染个体和易感个体之间进行接触时才会以概率β将疾病传染给易感个体。在时刻t,易感个体的比例为S(t)/N,感染个体的数量为I(t),一次,易感个体的数量将以如下变化率减少
    " k1 E3 J7 j' bds/dt = -β*S(t)I(t)/N
    1 z3 O) ~0 y" l' a同时,感染个体的数量会以与易感个体相反的变化率增加,
    ) {& B" c# p; |2 Hds/dt = βS(t)*I(t)/N) @' u/ z* Y) s3 B0 @  T+ Y
    分别将时刻t处于易感状态和感染状态的个体所占比例记为,* l  K' v. B: c2 R6 D+ b( j. [: `' V
    s(t)=S(t)/N/ e% A) O$ S3 \1 {) A
    i(t)=I(t)/N
    ; I" w" G8 D. ^3 A& z" x显然有,' `. ]- p$ C7 s( \. P2 r
    s(t)+i(t)恒等于1,此时之前的公式可以记做: i% T6 }# k+ q0 R0 N1 ~/ m2 @3 z
    ds/dt=-βsi
    ; v6 Y7 Y; Z  J. F" u; |di/dt=βsi9 ?( a, y* }- j# X4 n

    ! d2 X& i) X1 N. W- l/ F- a  Pdi/dt=βi(1-i)0 v, r) k5 [6 ^7 }7 y4 M
    上式也成为Logistic增长方程式(Logistic growth equation),
    : p! j3 e0 Q0 f$ {方程的解和图像如图
    4 |+ \+ Y' R# R0 c" z 1.jpg 1 \9 ]2 ^  T6 P& u8 q& g
    代码和相关文件以及环境链接:链接:https://pan.baidu.com/s/1JSfHuTPaglFimeEBLdSDyQ
    4 x& }" G+ I; ], e# e提取码:z448
    ! k, q6 A, A8 W; o1 O8 d$ z% Y
    7 U0 A. L5 Y/ Y, M+ M- j3 r
    % p% p# K* \7 z& x! e9 M'''5 Y6 _% x0 x8 V; a7 T- d
    实验环境Python2.7.13,igraph包,cairo包,numpy包( n, Q  M6 i* y1 ^
    '''( B, ?) v) X, h/ M. Z. H
    # -*- coding:utf8 -*
    ( f( q; f0 q$ Q6 X+ l" \from igraph import *3 K% ~: ]& c+ L
    import numpy as numpy
    4 Q. i* P8 Y" ], Y2 r5 V1 G: i, Xfrom  numpy import *
    7 ?! m8 {! N# ^: dimport random$ p/ L. C) r6 h% {; o8 e) B
    8 M* P0 P% d; Q( _
    def len_arr(infected_array,nodes_num):#获取感染数组长度
    # f( f/ H5 f+ |1 F( x3 O; |    len_value=0#初始化长度9 C. ~8 {5 m7 S9 z
        len_value=nodes_num-infected_array.count(-1)#被感染数量是结点总数减去未感染节点数(未感染的结点被标记为-1)
    1 g' y9 j# r) y    return len_value* B' b+ {8 Y5 \# O

    - Y5 t6 Z# k- Y. n# V; e, |: G3 |g=Graph.Read_GML("C:\python27\e1.gml")#将本地保存的网络数据读入变量g(生成图)
    3 O. z1 Q6 I5 i% y& B+ _# Isummary(g)  p% v/ M' ~; ~8 o" R; ~% v4 B" m
    nodes_num=g.vcount()#统计图中的结点个数; ]0 {5 p7 P) A% l$ q
    net_mat=g.get_adjacency(type=GET_ADJACENCY_BOTH)#将网络数据转换为邻接矩阵存储在变量net_mat
    & x) T5 H* B  \/ z9 v8 A% Og.vs["color"]=["white"]#给图的顶点序列颜色赋值白色, W1 l6 W4 b/ B* o9 A* @
    a=[arange(nodes_num)+1]*3#声明一个N行3列的数组a4 P1 S: I- O, i3 p
    nodes_state=matrix(a).T#nodes_state通过转置a矩阵创建,用于存放每个节点的状态信息以及其被感染的时间(这个是理解算法的重中之重!!!)# P" r( I7 E; r& _
                                                        #第一列是节点编号,第二列是节点状态,感染状态用-2表示,第三列是节点感染的时间
    ; ~' u7 e# I9 i% Dprint(nodes_state)
    7 `- J% V0 v8 f& @+ n+ Kinfected_array=[-1]*34#用于存放本轮被感染的结点, 这些结点将参与下一次感染   34代表网络节点数- l) s6 [) P; d8 E& X
    print(infected_array)! @- e/ c7 l7 `$ n- f

    * `! S- |3 F5 Z( H* G$ B; xinfe_rate=1#传播率(感染率) 1代表邻接点100%被感染
    8 Z& x( ^# q" z: y1 Gset_time=2#传播次数(感染次数) 2次0 F2 t; k) `" y
    source_seed=1#感染源位置7 x, H; G6 J4 x1 y
    nodes_state[0:nodes_num,2]=-1#给所有节点初始化感染时间为-14 j3 H2 h# v! u
    nodes_state[source_seed-1,1]=-2#设置第一个感染源感染状态 -2代表感染状态' k4 I/ ~# u2 {/ V1 Y) Z% Q
    nodes_state[source_seed-1,2]=1#设置第一个感染源的感染时间为1
    $ H7 ^$ b3 v& Q: G( Tg.vs[source_seed-1]["color"]="red"#将感染的顶点颜色标红
    " k1 {9 a' h/ G% t5 s% e( T+ e, }& hinfected_array[0]=source_seed#将感染源的位置存入被感染节点列表% K2 y) a# k* ?: j5 p3 G
    plot(g)#绘制
    " k# u5 ~1 r7 M+ q5 B! I' i
    , r/ u2 _; u6 astop=False#感染过程结束的标记0 S; V3 e" r, t: T9 z' l% v* e" Z
    temp_time=0#第几次感染3 H% f: `: h6 a1 d
    temp_len=0#本轮的感染源数量初始化8 g6 F: a0 n& b8 g  o8 X. S  V
      C; R: u1 q$ Y/ ]# {
    while not stop:% K  p# G3 N0 m4 Z: \7 }
        i=0#记录让每个感染源都传播一次4 y& `9 C' o/ t* W- S
        if len_arr(infected_array,nodes_num)>0 and len_arr(infected_array,nodes_num)<=nodes_num:#感染可以进行2 E- O- |9 A$ g( x7 g
            temp_len=len_arr(infected_array,nodes_num)#获取本轮的感染源数量! E0 N% S+ P2 m( W" i
            while i<temp_len:
    $ I6 F" k* b- R% g. r4 m( c3 k  i. e9 Z            temp_time=nodes_state[infected_array-1,2]#获取每一个节点的感染时间) D. o  P$ L" f6 }
                nei_count=0#下一轮可以被感染到的节点数量
    ) ]* `! Z" R% y            #生成下一轮可能被感染的节点的集合nei_arr1 q: i  r9 U' I% T6 E' J) l, R
                for j in range(nodes_num):#遍历节点
    8 u: I% \2 p0 f5 Z# H9 s                if net_mat[infected_array-1,j]==1 and nodes_state[j,1]!=-2:#是邻接节点而且未被感染
    : ]  A+ F. V' H. ?                    nei_count=nei_count+1#下一轮可以被感染到的节点数量++6 h- u- d4 ~7 V' Q, K/ y+ s$ n7 m
                nei_arr=[-1]*nei_count#用于临时存放本轮被感染的结点, 这些结点将参与下一次感染* V/ p. m( e% V2 u
                t=0
    ( I' O" q/ a' S$ T, e7 j            for j in range(nodes_num):9 f/ |% V3 k6 o6 e# f+ u
                    if net_mat[infected_array-1,j]==1 and nodes_state[j,1]!=-2:3 D9 ~) w# N9 `1 b/ N4 o1 }3 r# B2 W
                        nei_arr[t]=j+1
    : m, _  X- b# t  H                    t=t+1
    6 h; f( a$ ?8 o4 j            ran_infe_arr=random.sample(range(nei_count),int(nei_count*infe_rate))#随机生成会被感染的节点的数组0 H5 c4 `5 S" o9 K' ]5 N4 A
                                            #random.simple(arg1,num) 从arg1集合中随机取num个数据生成一个对象3 S' B8 B4 x8 p' V
                if len(ran_infe_arr)>0:#存在需要被感染的节点
    ! s& |; O/ x4 Z: @1 R) ?3 j                t=0#让ran_infe_arr内每个感染源都被感染, T( y2 F) G. a+ M6 m
                    while t<len(ran_infe_arr):#对刚才生成的会被感染的数组内的节点进行感染" O" Z, z8 E- \' f: k: ?2 ^" l% W
                        nodes_state[nei_arr[ran_infe_arr[t]]-1,1]=-2#标记为感染状态7 R; O. f+ Z9 J8 c4 T0 u4 o6 q
                        nodes_state[nei_arr[ran_infe_arr[t]]-1,2]=temp_time+1#记录感染时间& w6 U4 `2 L6 {% m9 h8 I+ O/ C
                        infected_array[len_arr(infected_array,nodes_num)]=nei_arr[ran_infe_arr[t]]#将此次感染节点放入总的感染节点数组中
    9 Y/ D% e4 n  Z1 [3 O# E  ~0 J                    g.vs[nei_arr[ran_infe_arr[t]]-1]["color"]="pink"#将此次感染的节点集的所有节点颜色置为粉色
    ; O$ A* z) Y% D/ b0 c                    plot(g)#绘制3 [  ^. d* _! A: p
                        t=t+1
    ' |, P8 i. j/ B% e  i% j9 l/ M            i=i+1
    0 u' t3 L, T0 ]8 Y+ R& s+ u( m1 l    if temp_time>set_time-1:#当执行感染的次数等于设置的次数结束感染$ b( ]3 C0 h/ t7 b/ o9 D5 P
            stop=True
    9 q+ L( t. Y+ U/ U
    2 _5 W- ~" I5 l8 B, \5 a; u" J4 N/ @; i
    视频演示bilibili传送门( a7 ?5 O3 d& G3 K% [  p
    效果图
    ( O4 j; i6 |* O3 s, q
    ( H  y4 P' u8 u6 ?% n9 _. b0 N1 p) p5 r7 W5 x
    2.jpg - _3 y! X* ]1 A. w

    / D6 G% Z9 v1 n( k4 F5 m/ T; W 3.png ' H  S7 y: f7 ]; a; s9 k

    % P. Z4 C0 I9 h$ p2 t: F 4.jpg ) Y  }9 [; C2 g  {* T

    ! @4 u/ z5 x8 Y" k7 s; I 5.png
      I/ I% C& s% N0 G2 \; t# S6 c. u# n
    6.png # v1 u& o/ I( B5 g) i
    ; g7 `! f' t  W# j8 D6 r! `9 l
    7.png ————————————————0 T* c" ~# \1 ^
    版权声明:本文为CSDN博主「eck_燃」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
      {9 v5 o& ~; b+ C" W0 A原文链接:https://blog.csdn.net/wdays83892469/article/details/808788624 G. y* C2 N( k

    6 l+ W# }5 Z4 M/ C$ q9 E( _  e1 @& J" w6 S9 g' b1 ~# F
    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-4-20 13:31 , Processed in 0.595343 second(s), 59 queries .

    回顶部