QQ登录

只需要一步,快速开始

 注册地址  找回密码
查看: 3120|回复: 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传播模型
      r- q! u3 F7 H3 H; y9 }#SI疾病传播模型的原理
    0 d9 D2 m/ H" [# m  K1 f- h- \  y& W2 D在经典的传染病模型中,种群(Population)内N个个体的状态可分为如下几类
    9 X! R3 a" Q: s# z( z/ f( L2 T* b8 x8 T
    易感状态(Susceptible)。一个个体在感染前是处于易感状态的,即该个体有可能被邻居个体感染。8 U" f7 @6 F# j# F6 r
    易感状态I(Infected)。一个感染上某种病毒的个体就称为是处于感染状态。,即该个体还会以一定概率感染其邻居个体。" \, P) S9 Z# V9 Y
    移除状态(Remove,Refractory或者Recovered)。也成为免疫状态或恢复状态,当一个个体经历过一个完整的感染周期后,该个体就不再被感染,因此就可以不再考虑改革提。% H, Z; m, I/ d5 {: A. h
    SI传播模型是最简单的疾病传播模型,模型中的所有个体都只可能处于两个状态中的一个
    % J" f* {8 G- U即易感(S)状态或感染(I)状态。SI模型中的个体一旦被感染后就永远处于感染状态。
    6 r$ d. U3 ^$ ~6 O' O2 i: h在给定时刻t,令S(t)与I(t)分别代表该时刻处于易感和感染状态的个体数目,显然有
    6 C% M9 L  ?  i: @7 r5 v' b* dS(t)+I(t)恒等于N,这里,N是个体总数。随着时间t的增长,易感个体与感染个体的接触6 w/ t8 b& v$ ^. G* h0 `7 k# H: X
    会导致感染个体数量的增加。加入由于个体之间的接触而导致疾病传播的概率为β,疾病仅在
      y5 U) T! p, H! u8 i6 d感染个体和易感个体之间进行接触时才会以概率β将疾病传染给易感个体。在时刻t,易感个体的比例为S(t)/N,感染个体的数量为I(t),一次,易感个体的数量将以如下变化率减少
    2 P  \+ O' D; E- m+ Z: |  dds/dt = -β*S(t)I(t)/N7 ^& C. {  G$ ?% n, r9 t0 {5 h0 f9 B
    同时,感染个体的数量会以与易感个体相反的变化率增加,% h0 \+ @% Z/ z
    ds/dt = βS(t)*I(t)/N
    7 e* G8 v9 L; e$ `分别将时刻t处于易感状态和感染状态的个体所占比例记为,: Q% O3 Y! T/ ^
    s(t)=S(t)/N# M; Q, W4 V  _# i0 P- @5 Y7 D# m
    i(t)=I(t)/N1 L2 Y1 T8 d$ D1 z9 k/ _' s7 C% {
    显然有,
    5 R2 D: V: L5 w9 p. ms(t)+i(t)恒等于1,此时之前的公式可以记做9 ]4 I0 m3 y( a9 _* B, n, m; ?
    ds/dt=-βsi# j. g$ o( m! M0 a7 ~; K
    di/dt=βsi
    9 q3 f. ?+ n- K  {' b% U# D9 I; v( h* h
    $ o% O. d0 R, Odi/dt=βi(1-i)- R% f+ s9 a$ ^& j; p
    上式也成为Logistic增长方程式(Logistic growth equation),
    # F0 N- v. I; D% j4 K方程的解和图像如图/ N! M# K! t7 }8 d( e: {5 U
    1.jpg - a* P; l) `9 x
    代码和相关文件以及环境链接:链接:https://pan.baidu.com/s/1JSfHuTPaglFimeEBLdSDyQ4 F+ b  B7 w- m$ S+ t. P
    提取码:z448
    ! Y/ R- I6 D- i( t7 E& Q' g. _: L3 j8 R' Z/ |) X  e3 O

      C0 p; a0 ]" `/ u, A'''
    $ w( R: g+ N' [4 I4 _6 n实验环境Python2.7.13,igraph包,cairo包,numpy包" Q/ w: W7 t, `2 s
    '''* y& C. y9 _7 r; I; S0 Y
    # -*- coding:utf8 -*8 B6 ?' |- R9 p6 u/ T
    from igraph import *
    , e/ \6 w3 Q9 n; m# D2 l+ ?- Uimport numpy as numpy
    + @; q" v/ |& \+ }; @& J0 `from  numpy import *
    5 {/ W9 }9 n0 z9 N# himport random
    ) [7 _* n: I! {+ i" N4 q) A, }" y, E5 L
    def len_arr(infected_array,nodes_num):#获取感染数组长度  _' g9 i* C5 I
        len_value=0#初始化长度0 n- V3 ?: E1 Y, m- _8 n
        len_value=nodes_num-infected_array.count(-1)#被感染数量是结点总数减去未感染节点数(未感染的结点被标记为-1), m* h2 r3 l6 \' U7 M- S
        return len_value
    ) z! J$ ?' \7 p' z5 X" W$ l
    , {% X; Z, A+ p  e( j8 rg=Graph.Read_GML("C:\python27\e1.gml")#将本地保存的网络数据读入变量g(生成图)
    & @/ A1 B$ R9 [2 p. K6 Rsummary(g)
    7 `5 v* v& B; @nodes_num=g.vcount()#统计图中的结点个数# a% u3 P6 x# u3 X) |# C
    net_mat=g.get_adjacency(type=GET_ADJACENCY_BOTH)#将网络数据转换为邻接矩阵存储在变量net_mat8 Y% M; W! S" }& p1 \$ u  k. {
    g.vs["color"]=["white"]#给图的顶点序列颜色赋值白色2 M( G: U1 h' i5 [. E8 X( [3 c! B
    a=[arange(nodes_num)+1]*3#声明一个N行3列的数组a) l; k7 l9 g3 ?# w
    nodes_state=matrix(a).T#nodes_state通过转置a矩阵创建,用于存放每个节点的状态信息以及其被感染的时间(这个是理解算法的重中之重!!!)
    6 m$ t+ H1 Z" S6 z5 L                                                    #第一列是节点编号,第二列是节点状态,感染状态用-2表示,第三列是节点感染的时间
    + _) k! [' E+ C6 T9 S3 x/ gprint(nodes_state)* x0 F( ?* `6 p3 n4 r/ h
    infected_array=[-1]*34#用于存放本轮被感染的结点, 这些结点将参与下一次感染   34代表网络节点数8 ~0 R$ r+ p6 [) G0 b7 [# c
    print(infected_array)
    ; \2 P: n# P$ B/ @
    1 b- v) V3 V6 [* w/ I+ oinfe_rate=1#传播率(感染率) 1代表邻接点100%被感染
      }0 J: u% w" L1 ]# ~4 {set_time=2#传播次数(感染次数) 2次! k4 V5 i( y2 S& W! z
    source_seed=1#感染源位置
    8 |6 M. ]; g) w2 Z' Onodes_state[0:nodes_num,2]=-1#给所有节点初始化感染时间为-1
    5 N5 {: B! v7 `4 z8 j) _8 M! h* Unodes_state[source_seed-1,1]=-2#设置第一个感染源感染状态 -2代表感染状态# [& o9 Q/ B0 Y$ Y& i
    nodes_state[source_seed-1,2]=1#设置第一个感染源的感染时间为1% i8 {+ e; z( @& L# q
    g.vs[source_seed-1]["color"]="red"#将感染的顶点颜色标红
    " F7 h; ]/ [( {  m. l% b6 @infected_array[0]=source_seed#将感染源的位置存入被感染节点列表
    9 |4 Z7 }- e9 Iplot(g)#绘制
      T7 ?' h! N' o
    7 s, i: `* H: H: y1 N, V/ y0 [4 i# [stop=False#感染过程结束的标记
    ) ~, B" l# S: M2 O0 d' c  t6 `temp_time=0#第几次感染; ^* V- t5 s$ a) e7 m; c
    temp_len=0#本轮的感染源数量初始化' _) g4 }* W' M/ {
    8 U, K* A3 u% j: F
    while not stop:: B) }* G; z0 `; S( a+ r# U
        i=0#记录让每个感染源都传播一次
    ) G7 N4 v2 V3 H, l4 k6 j    if len_arr(infected_array,nodes_num)>0 and len_arr(infected_array,nodes_num)<=nodes_num:#感染可以进行  d! F$ [# s5 K% C8 S4 y
            temp_len=len_arr(infected_array,nodes_num)#获取本轮的感染源数量
    " o2 T" T' {8 u' v( V% m+ G        while i<temp_len:7 p4 s: X9 n; G# I" n3 V
                temp_time=nodes_state[infected_array-1,2]#获取每一个节点的感染时间
    * ]7 [% g8 J/ i! S  Q            nei_count=0#下一轮可以被感染到的节点数量: J- u' J0 {  G! f- T( s
                #生成下一轮可能被感染的节点的集合nei_arr
    . m" S6 j- G2 R9 o            for j in range(nodes_num):#遍历节点/ m  W( @; _2 d' p
                    if net_mat[infected_array-1,j]==1 and nodes_state[j,1]!=-2:#是邻接节点而且未被感染
    7 q, M( g4 X) w& a6 Q                    nei_count=nei_count+1#下一轮可以被感染到的节点数量++
    * Y$ s, g' ~2 P8 ?            nei_arr=[-1]*nei_count#用于临时存放本轮被感染的结点, 这些结点将参与下一次感染1 ~6 d- L: u$ t# D+ p0 @
                t=0
    . m% _7 v5 Z4 R0 ]- Y7 S; `, c            for j in range(nodes_num):
    5 D* S) L+ i& Q$ y. v& M$ ~- H                if net_mat[infected_array-1,j]==1 and nodes_state[j,1]!=-2:* C% F6 Z8 u) X
                        nei_arr[t]=j+1) e4 C. u9 R1 J  B: w
                        t=t+1: f( Q" ~: S6 H6 h
                ran_infe_arr=random.sample(range(nei_count),int(nei_count*infe_rate))#随机生成会被感染的节点的数组8 G% W9 Y- b# F9 o. a5 D1 V7 f
                                            #random.simple(arg1,num) 从arg1集合中随机取num个数据生成一个对象
    ' Y, s9 e: h& |9 a            if len(ran_infe_arr)>0:#存在需要被感染的节点
    $ @& [0 d% w" T" `% W8 i                t=0#让ran_infe_arr内每个感染源都被感染6 |& s$ d( C$ |* P, ~  Z0 C  ?/ ?
                    while t<len(ran_infe_arr):#对刚才生成的会被感染的数组内的节点进行感染" ^% Y  K+ p" I( ]8 u6 g. T
                        nodes_state[nei_arr[ran_infe_arr[t]]-1,1]=-2#标记为感染状态  w  t5 f0 u# O0 w6 s5 k
                        nodes_state[nei_arr[ran_infe_arr[t]]-1,2]=temp_time+1#记录感染时间
    ; E1 `# `% o0 D/ R, n7 H! ~                    infected_array[len_arr(infected_array,nodes_num)]=nei_arr[ran_infe_arr[t]]#将此次感染节点放入总的感染节点数组中  H% w/ q) s# f- {& U3 J3 L  e
                        g.vs[nei_arr[ran_infe_arr[t]]-1]["color"]="pink"#将此次感染的节点集的所有节点颜色置为粉色0 D$ i4 y  D+ }2 g" D4 s; I4 ~
                        plot(g)#绘制3 D8 Z5 K" @. f
                        t=t+1
    # s, M+ E0 \6 q& o  d0 ~9 a; \            i=i+1  V3 e" y" u3 a
        if temp_time>set_time-1:#当执行感染的次数等于设置的次数结束感染
    ' k! a1 J5 i' }        stop=True
    + Q  J# w. q, \- h/ l3 Z9 x* L+ s! U8 ?) q6 g$ l+ r# m# \" C" A0 m( E
    8 v6 A: d3 v: |& u" ?* d2 j. o
    视频演示bilibili传送门
    6 }; s0 r/ P# o效果图7 s0 r# _6 d* u1 E7 @: W$ u

    $ Y5 K- N: {/ z. Z# `  \
    ; s$ E+ t& r! b, h' U; W 2.jpg ' e( v6 K4 O- i+ C* C& Z0 P

    ) F* [1 f' ?7 O+ J1 a, @/ p, |1 n 3.png
      e' ?' ~. Y/ B% \9 Q/ R' H1 {  b" h: Z* Q
    4.jpg
    ! i0 c! b- V, R" v, e: \7 v5 ^
    1 L) Q( ~3 U* k5 p% r% d( ` 5.png ) L( o: l( V. A- H

    9 U1 F/ n8 ^/ L7 T 6.png 2 V! b8 u) K( Y1 @% V. G" M1 K! R( k
    6 X- C' {+ K! `" R
    7.png ————————————————
    " G9 k* a+ u4 ]' c" H版权声明:本文为CSDN博主「eck_燃」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
    + ~/ H5 p& |4 l* ?; D. ]原文链接:https://blog.csdn.net/wdays83892469/article/details/80878862
    + w8 X) N8 ?8 N% T0 K9 g0 i" v. M' m1 i

    . E/ m2 W$ d. Q# \1 h
    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 05:30 , Processed in 0.468907 second(s), 59 queries .

    回顶部