QQ登录

只需要一步,快速开始

 注册地址  找回密码
查看: 3097|回复: 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传播模型# u6 g) V& S2 M( f& W
    #SI疾病传播模型的原理) p9 a5 |8 T6 x/ i
    在经典的传染病模型中,种群(Population)内N个个体的状态可分为如下几类2 p; Z% x5 `: L, Q- Q( e

    ! v2 y1 T+ J' c5 G# s( _) a6 T易感状态(Susceptible)。一个个体在感染前是处于易感状态的,即该个体有可能被邻居个体感染。! g. {# {# o* u1 X$ i
    易感状态I(Infected)。一个感染上某种病毒的个体就称为是处于感染状态。,即该个体还会以一定概率感染其邻居个体。) ?- W& q; j/ e) B( `
    移除状态(Remove,Refractory或者Recovered)。也成为免疫状态或恢复状态,当一个个体经历过一个完整的感染周期后,该个体就不再被感染,因此就可以不再考虑改革提。
    3 [. E  u, G4 f/ A8 ^SI传播模型是最简单的疾病传播模型,模型中的所有个体都只可能处于两个状态中的一个
    , }5 q' z8 c; v6 X; Q即易感(S)状态或感染(I)状态。SI模型中的个体一旦被感染后就永远处于感染状态。
    " T6 t7 Q* V/ A$ A3 W4 P在给定时刻t,令S(t)与I(t)分别代表该时刻处于易感和感染状态的个体数目,显然有+ C: O1 x: j: L0 ~* P! X% H% X
    S(t)+I(t)恒等于N,这里,N是个体总数。随着时间t的增长,易感个体与感染个体的接触
    6 m  x  }- O% ]( a3 g& ^3 w% O会导致感染个体数量的增加。加入由于个体之间的接触而导致疾病传播的概率为β,疾病仅在0 o# q7 j7 {0 L/ m8 P4 K/ @2 D* w
    感染个体和易感个体之间进行接触时才会以概率β将疾病传染给易感个体。在时刻t,易感个体的比例为S(t)/N,感染个体的数量为I(t),一次,易感个体的数量将以如下变化率减少- Z9 e8 N9 z7 k% Z: c& e8 L1 k3 I2 t
    ds/dt = -β*S(t)I(t)/N
    1 |$ ^" O* r; ~9 T% h同时,感染个体的数量会以与易感个体相反的变化率增加,4 X1 j) U- P3 R) {- I  R2 H* B& x8 F
    ds/dt = βS(t)*I(t)/N6 }1 {3 R/ Q; {. N0 Y
    分别将时刻t处于易感状态和感染状态的个体所占比例记为," D0 J4 H$ G& C& G
    s(t)=S(t)/N0 r% ]+ s& T# f6 ]9 m' J. X2 d
    i(t)=I(t)/N
    # q; [4 M  M" @: K7 m显然有,
    + M2 Y7 V$ a  {( h' f; b. o6 \s(t)+i(t)恒等于1,此时之前的公式可以记做9 j, S$ a5 i, }' _4 `
    ds/dt=-βsi
    : y; m5 }: o0 n6 Odi/dt=βsi
    " [9 R6 s& ~# H' L6 e& K. T4 G
    " g9 f2 \" O" U; odi/dt=βi(1-i)
    ; t1 n1 x! l  j  E+ S+ @上式也成为Logistic增长方程式(Logistic growth equation),
    : J' ^9 Q7 l1 ~3 ?6 X- V: E  a& e# c方程的解和图像如图
    1 I. L! l; k0 C" P7 d+ `  P1 o 1.jpg ' z  U5 K, ~: a
    代码和相关文件以及环境链接:链接:https://pan.baidu.com/s/1JSfHuTPaglFimeEBLdSDyQ
    $ f# f$ I% c: j$ z7 B+ o' K  X6 P提取码:z448
    ( E8 f7 j+ X! |' _7 k( L1 k& E" |) m; I0 `
    4 S+ j* `2 i( z+ C
    '''
    2 H& Y/ I1 T/ ]$ ^实验环境Python2.7.13,igraph包,cairo包,numpy包1 n# B: p9 N, G0 `- V% Q3 Q
    '''( @, N  X# p' b0 ]2 F
    # -*- coding:utf8 -*
    ) h$ |, Y! U) D/ T! L8 A+ @8 zfrom igraph import *
    * r1 t: s* M6 \& Uimport numpy as numpy
    , l' X# J3 X. z; J% A& Jfrom  numpy import ** {7 c* I* F' U/ k' l
    import random
    / \. k: i' G: R  q  `
    ; V( J6 F" W: M# s9 b# c6 a/ e% `& mdef len_arr(infected_array,nodes_num):#获取感染数组长度
    5 W' w& t# h5 I/ O9 H( X1 E& ~6 y4 @    len_value=0#初始化长度! M( I; R) l; h' m1 w
        len_value=nodes_num-infected_array.count(-1)#被感染数量是结点总数减去未感染节点数(未感染的结点被标记为-1)
    + ^% @1 z( f5 g    return len_value( X4 s; b  n3 d
    8 O% e( J) S7 S& ~
    g=Graph.Read_GML("C:\python27\e1.gml")#将本地保存的网络数据读入变量g(生成图)
    4 B( W; s; U* M( O' _0 ?summary(g)$ G4 X" p" b( E( O
    nodes_num=g.vcount()#统计图中的结点个数1 K& j) i' C6 z; ^* R1 G
    net_mat=g.get_adjacency(type=GET_ADJACENCY_BOTH)#将网络数据转换为邻接矩阵存储在变量net_mat
    6 l  r2 ^- u0 q8 q: E2 ag.vs["color"]=["white"]#给图的顶点序列颜色赋值白色9 ?: X3 Y; Z4 ]2 C. b0 U9 }
    a=[arange(nodes_num)+1]*3#声明一个N行3列的数组a
    ' h1 h9 L% E$ Y/ `; d1 [nodes_state=matrix(a).T#nodes_state通过转置a矩阵创建,用于存放每个节点的状态信息以及其被感染的时间(这个是理解算法的重中之重!!!)
    + c7 D) L7 {8 C: X# ~8 a& B1 A, S                                                    #第一列是节点编号,第二列是节点状态,感染状态用-2表示,第三列是节点感染的时间
    2 ~# H! R! L6 V7 I$ b0 R8 sprint(nodes_state)4 t2 r/ C, t6 ?2 l* C' `; ~' [
    infected_array=[-1]*34#用于存放本轮被感染的结点, 这些结点将参与下一次感染   34代表网络节点数) S# O# E) U% w3 a4 L5 s$ X
    print(infected_array)
    6 E, ]' _) j$ t( Z# T7 {
    ! v# ^# `% t1 z% h5 I) Z% t' ginfe_rate=1#传播率(感染率) 1代表邻接点100%被感染, c: ~, W; ?; ^* ]
    set_time=2#传播次数(感染次数) 2次. K/ w* U9 u% N+ }- Y' G* d% U
    source_seed=1#感染源位置
    5 _! y1 \/ n6 ~7 H1 Dnodes_state[0:nodes_num,2]=-1#给所有节点初始化感染时间为-1
    ; k5 ~) f5 v! c% N$ n* Knodes_state[source_seed-1,1]=-2#设置第一个感染源感染状态 -2代表感染状态
    3 m' m) M8 i/ b# `0 T" Fnodes_state[source_seed-1,2]=1#设置第一个感染源的感染时间为1
    & s+ U/ Y" _# X8 \1 ^  W1 sg.vs[source_seed-1]["color"]="red"#将感染的顶点颜色标红
    3 p6 n' y1 D8 a# C$ |2 m( ~infected_array[0]=source_seed#将感染源的位置存入被感染节点列表3 k/ R' }  D5 A7 |7 ~: I
    plot(g)#绘制
    % d( T1 m( ]: }' @
    . {- [, z9 t( G; R% y( Sstop=False#感染过程结束的标记, m: \5 W9 @* d- V& I- r
    temp_time=0#第几次感染
    ! n6 G! Q7 s: C# T9 K+ htemp_len=0#本轮的感染源数量初始化3 z" X4 ^) j& h* y

    ' Y- [2 O. o- ?5 H( u  fwhile not stop:; D" U. O) t* m, g& p$ m* k$ u
        i=0#记录让每个感染源都传播一次. N! w8 k( l( W' B2 n! ^! `0 @- h' H
        if len_arr(infected_array,nodes_num)>0 and len_arr(infected_array,nodes_num)<=nodes_num:#感染可以进行
    " `$ c6 M- Q5 q  w+ c        temp_len=len_arr(infected_array,nodes_num)#获取本轮的感染源数量
    : C/ H7 [# F" _        while i<temp_len:8 K$ [5 \, x0 Q, }
                temp_time=nodes_state[infected_array-1,2]#获取每一个节点的感染时间
    $ q  ]0 g1 ]; _5 k0 c% k            nei_count=0#下一轮可以被感染到的节点数量# C: [/ B- ^7 S' v* u; d% g
                #生成下一轮可能被感染的节点的集合nei_arr
    $ @; m" ^5 _9 J) n) p6 [! b: ~9 Q% }  N. |            for j in range(nodes_num):#遍历节点4 w- i( x# l) C8 ^/ @
                    if net_mat[infected_array-1,j]==1 and nodes_state[j,1]!=-2:#是邻接节点而且未被感染
    % C* X) N. c6 v8 ^+ `* f" |                    nei_count=nei_count+1#下一轮可以被感染到的节点数量++
    ) a; h5 X1 o. p! ]3 \5 a+ [            nei_arr=[-1]*nei_count#用于临时存放本轮被感染的结点, 这些结点将参与下一次感染# Z5 J0 K7 S) x# {; H
                t=0
      j# U) g! \% ]$ S/ v            for j in range(nodes_num):
    0 f2 h( {1 o1 g* h" Y5 h3 }                if net_mat[infected_array-1,j]==1 and nodes_state[j,1]!=-2:
    7 H3 [. |* `8 O  L7 T: N                    nei_arr[t]=j+1
    ) x$ b5 R2 `7 x' g) |3 V                    t=t+1
    0 s* U2 ?2 D' c7 S+ a: R            ran_infe_arr=random.sample(range(nei_count),int(nei_count*infe_rate))#随机生成会被感染的节点的数组
    & Y: b$ b( O: Z# L                                        #random.simple(arg1,num) 从arg1集合中随机取num个数据生成一个对象
    , r( ?) n2 i8 Q& @/ [) Z* r; C            if len(ran_infe_arr)>0:#存在需要被感染的节点/ J: ]. X' m* H( X& O5 N
                    t=0#让ran_infe_arr内每个感染源都被感染
    ! t& ]! h6 w" L! D5 B" ]9 h- M                while t<len(ran_infe_arr):#对刚才生成的会被感染的数组内的节点进行感染4 w4 i! J' O, `8 g4 w; Q
                        nodes_state[nei_arr[ran_infe_arr[t]]-1,1]=-2#标记为感染状态
    % U+ k8 s) r% |% o5 T  _                    nodes_state[nei_arr[ran_infe_arr[t]]-1,2]=temp_time+1#记录感染时间
    1 O' |( U8 ]+ s                    infected_array[len_arr(infected_array,nodes_num)]=nei_arr[ran_infe_arr[t]]#将此次感染节点放入总的感染节点数组中8 L, G% x5 V! ~' `4 {
                        g.vs[nei_arr[ran_infe_arr[t]]-1]["color"]="pink"#将此次感染的节点集的所有节点颜色置为粉色
    ' }; ~" r0 A; H                    plot(g)#绘制, H, P) b# s5 |4 X5 Q* P: V
                        t=t+12 \5 t0 W5 b& b, Y" f8 B
                i=i+1
    / S" X; U  }( h% c& S    if temp_time>set_time-1:#当执行感染的次数等于设置的次数结束感染) P9 g: p& p& J4 k, t* _& Z! v, L
            stop=True 0 D" ]1 F" q4 h4 n

    4 M; ]9 ~- R: H! d' Y
    7 B* @, B' i% @0 O* ]. z2 B视频演示bilibili传送门" J8 Y( P% g+ R, X% Z' `; p
    效果图
    " v: w, q7 _* q5 A! T
    4 R' g& Z1 {- c! x4 w1 t& G! d, u( _9 T6 M
    2.jpg / s4 E3 ~- z, U- b# w
    & u4 u1 M4 }+ I& ~1 v1 b$ z0 a6 Q
    3.png
    . O8 C6 n& o5 O  T3 {
    2 d; K& U* d" {6 O! C: e4 A 4.jpg & C1 Z( G9 }  g
    $ [) g2 ^( c2 Q; r7 w
    5.png
    ! C. O7 H+ e5 K+ j! f+ R. ^5 m/ H" l; H* W4 p# g! p' X
    6.png   W" J1 v% ], z+ O1 R! Y
    , F$ e6 T1 S* q0 ~+ R$ M3 D
    7.png ————————————————
    6 p3 |9 P6 z: A版权声明:本文为CSDN博主「eck_燃」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
    " ~3 ?3 ?7 ]& }& W6 S/ |4 U原文链接:https://blog.csdn.net/wdays83892469/article/details/80878862
    ; k% I( \1 q6 L. F/ B0 v
    4 W2 a% l3 y* i8 C
    " j& t) B* l6 S6 E# T
    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-9 16:46 , Processed in 0.433826 second(s), 58 queries .

    回顶部