QQ登录

只需要一步,快速开始

 注册地址  找回密码
查看: 3093|回复: 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传播模型! V* O4 F* c) W4 ?  N
    #SI疾病传播模型的原理
    1 i( ?$ p; Q) p% g  E在经典的传染病模型中,种群(Population)内N个个体的状态可分为如下几类# E! y- b' N2 |5 b
    ( v9 D4 ]2 K6 Z! a( m' f/ x3 B. @8 b& _
    易感状态(Susceptible)。一个个体在感染前是处于易感状态的,即该个体有可能被邻居个体感染。" a0 M8 u2 a8 m, g& l
    易感状态I(Infected)。一个感染上某种病毒的个体就称为是处于感染状态。,即该个体还会以一定概率感染其邻居个体。
    $ d) Q/ @* X( a移除状态(Remove,Refractory或者Recovered)。也成为免疫状态或恢复状态,当一个个体经历过一个完整的感染周期后,该个体就不再被感染,因此就可以不再考虑改革提。) a5 Y, A; Y! S2 F# [! x$ Y" W
    SI传播模型是最简单的疾病传播模型,模型中的所有个体都只可能处于两个状态中的一个3 d' C9 k6 E" M* j" _
    即易感(S)状态或感染(I)状态。SI模型中的个体一旦被感染后就永远处于感染状态。2 e7 \4 W0 K4 O9 z( a3 u
    在给定时刻t,令S(t)与I(t)分别代表该时刻处于易感和感染状态的个体数目,显然有
    # @/ ~. X" R( HS(t)+I(t)恒等于N,这里,N是个体总数。随着时间t的增长,易感个体与感染个体的接触& j+ d: d" F+ m: o9 U, n
    会导致感染个体数量的增加。加入由于个体之间的接触而导致疾病传播的概率为β,疾病仅在
    5 s9 W. Z3 Z$ G1 f) e' b5 O) Z感染个体和易感个体之间进行接触时才会以概率β将疾病传染给易感个体。在时刻t,易感个体的比例为S(t)/N,感染个体的数量为I(t),一次,易感个体的数量将以如下变化率减少
    0 ]/ F6 C- Q4 R& b; mds/dt = -β*S(t)I(t)/N
    8 J7 W+ k& V5 m' W6 R同时,感染个体的数量会以与易感个体相反的变化率增加,
    " o- |/ ]: H: E# A- jds/dt = βS(t)*I(t)/N5 k1 w4 o3 R! H3 _( C3 ~0 l! O
    分别将时刻t处于易感状态和感染状态的个体所占比例记为,
    : w) \. L2 u7 D4 _2 R. s; ~: c2 \s(t)=S(t)/N
      q3 {" y5 A$ [7 W* a3 w) {i(t)=I(t)/N
    # H4 j$ {- G; x& D4 ?3 l$ K显然有,3 G2 W3 U2 Y" ?0 @4 W
    s(t)+i(t)恒等于1,此时之前的公式可以记做
    0 ?$ W. `0 a% _: q% G3 `. b  Uds/dt=-βsi
    $ \  L' p! H5 q4 |& Fdi/dt=βsi) F: R! H5 M+ W0 s8 I/ W0 a
    ! W# @5 x7 X" w" @. k3 Y# f
    di/dt=βi(1-i)( d# ?2 f9 v. s1 `  A# L
    上式也成为Logistic增长方程式(Logistic growth equation),
    ; `& q- ^5 R6 U. y* r方程的解和图像如图/ p7 d. O* P* \0 j9 i
    1.jpg " `( A) U. n9 u
    代码和相关文件以及环境链接:链接:https://pan.baidu.com/s/1JSfHuTPaglFimeEBLdSDyQ5 m1 o8 K5 Z3 S: i( p0 f: }# \4 C
    提取码:z448
    / d% _) K" Y4 j" ^
    ; @' @0 z( v: A( D
    2 A' ~- A0 C. e3 n  W'''
    3 s# I/ b' j" b! y3 e: C实验环境Python2.7.13,igraph包,cairo包,numpy包
    5 y5 t$ I- o; U/ W1 x'''
    4 X! g( o+ I/ y8 P# -*- coding:utf8 -*! K2 z% V$ X: t
    from igraph import *" I8 ~9 O" `. T# a& y
    import numpy as numpy# f7 n/ B% P$ a/ B6 Q
    from  numpy import *
    8 N5 m% l/ @) T2 Limport random
    . {7 [3 p+ l& y# Y( E; ^! n- m  b3 [' J8 {4 \9 C/ A
    def len_arr(infected_array,nodes_num):#获取感染数组长度
    % |4 k# I: d; `6 K6 H    len_value=0#初始化长度( k" y* M1 b7 V: H7 T
        len_value=nodes_num-infected_array.count(-1)#被感染数量是结点总数减去未感染节点数(未感染的结点被标记为-1)1 N& a2 q1 V7 v7 p! v
        return len_value) Y# w- F3 b; g" r* W
    7 T) d  O: D# ?- D  {+ |5 v5 q2 _
    g=Graph.Read_GML("C:\python27\e1.gml")#将本地保存的网络数据读入变量g(生成图)
    - v! m3 L" K$ C8 Zsummary(g)6 }6 \5 J- o' T/ S3 m/ d, `. k3 i
    nodes_num=g.vcount()#统计图中的结点个数) t6 M8 i' }, y4 F. U& Z( ?
    net_mat=g.get_adjacency(type=GET_ADJACENCY_BOTH)#将网络数据转换为邻接矩阵存储在变量net_mat
    * T1 e  L5 O1 \8 g# {g.vs["color"]=["white"]#给图的顶点序列颜色赋值白色
    * @% v* E  m, H6 [% }a=[arange(nodes_num)+1]*3#声明一个N行3列的数组a
    $ Z9 `( o) H" R, a" hnodes_state=matrix(a).T#nodes_state通过转置a矩阵创建,用于存放每个节点的状态信息以及其被感染的时间(这个是理解算法的重中之重!!!)
    + o9 T) i/ I0 I) ?9 _' [' ^                                                    #第一列是节点编号,第二列是节点状态,感染状态用-2表示,第三列是节点感染的时间
    7 i; I, |  q' q( ?" B8 [print(nodes_state)  d8 A8 [3 \" T4 q7 b5 C' F6 f
    infected_array=[-1]*34#用于存放本轮被感染的结点, 这些结点将参与下一次感染   34代表网络节点数
    . v" @! L( _3 N5 F9 aprint(infected_array)$ x+ C) w7 A* G) v
    ( R9 z: ]: g. N
    infe_rate=1#传播率(感染率) 1代表邻接点100%被感染8 P; a6 e0 H7 `) c
    set_time=2#传播次数(感染次数) 2次+ z9 z+ K, T9 u! r3 g
    source_seed=1#感染源位置6 R2 F$ E0 l: c% M/ e
    nodes_state[0:nodes_num,2]=-1#给所有节点初始化感染时间为-1
    ) ]9 a" F: b' a5 t" Q7 K: K% v8 S$ Xnodes_state[source_seed-1,1]=-2#设置第一个感染源感染状态 -2代表感染状态/ T# ?3 z' k) U8 {- ]
    nodes_state[source_seed-1,2]=1#设置第一个感染源的感染时间为1& D! m7 I% c9 j/ q. D
    g.vs[source_seed-1]["color"]="red"#将感染的顶点颜色标红
    / R) k& w* [2 ~- p  hinfected_array[0]=source_seed#将感染源的位置存入被感染节点列表
    " V/ f1 K+ W* {9 M9 t% Q0 a9 J! X* r, Pplot(g)#绘制
    $ i% @7 R; A5 b3 o( s1 U& N  x# b% c( b+ v) z* Y4 [0 Y; F3 g- g' ^7 _
    stop=False#感染过程结束的标记% e9 M$ U  W% U0 M3 D9 M& v. R
    temp_time=0#第几次感染
    % L# `; _+ `- J7 x% m' w- c' ~temp_len=0#本轮的感染源数量初始化
    * M/ t. n  d0 Y* n5 S; T1 k: V, }  E3 Y
    while not stop:
    9 a2 a! H. q. ~* P2 Y2 {, f' u    i=0#记录让每个感染源都传播一次. X8 N4 r; r5 W' t9 Y  ?1 l" B
        if len_arr(infected_array,nodes_num)>0 and len_arr(infected_array,nodes_num)<=nodes_num:#感染可以进行
    5 t. p% H2 W. j4 ^3 h" L$ E8 x5 ]        temp_len=len_arr(infected_array,nodes_num)#获取本轮的感染源数量
    * L* N- d4 s2 l& s, r8 T2 o        while i<temp_len:
      C# i6 B4 M. i; h            temp_time=nodes_state[infected_array-1,2]#获取每一个节点的感染时间9 m4 u4 K; d7 |# L. N
                nei_count=0#下一轮可以被感染到的节点数量
    # A; M# ^8 Z+ e) o- s8 E0 I1 J" n            #生成下一轮可能被感染的节点的集合nei_arr
    & A) z" n: V5 |* `1 J            for j in range(nodes_num):#遍历节点
    6 Q1 Z+ l; F% }$ Y8 y                if net_mat[infected_array-1,j]==1 and nodes_state[j,1]!=-2:#是邻接节点而且未被感染+ z# F/ v- O3 R$ r4 g6 o
                        nei_count=nei_count+1#下一轮可以被感染到的节点数量++: h) p& ^$ u* E" b: H7 m+ e6 |
                nei_arr=[-1]*nei_count#用于临时存放本轮被感染的结点, 这些结点将参与下一次感染$ E  j7 k1 q+ S7 ?, A
                t=0
    * K1 L2 U7 ^7 s$ W8 |* d+ z            for j in range(nodes_num):
    , P0 @" N& e9 k" o                if net_mat[infected_array-1,j]==1 and nodes_state[j,1]!=-2:
    , n+ m7 z' z" N& R& g; W7 r8 u6 g                    nei_arr[t]=j+1' `9 F" R' k6 G5 S5 Y
                        t=t+1
    3 _1 @8 Y$ \+ p& X) W. q            ran_infe_arr=random.sample(range(nei_count),int(nei_count*infe_rate))#随机生成会被感染的节点的数组
    % n+ l1 T% d4 h" D$ u                                        #random.simple(arg1,num) 从arg1集合中随机取num个数据生成一个对象
    % t7 H& @; a( u" ^            if len(ran_infe_arr)>0:#存在需要被感染的节点/ f- ^! V/ D* q- z) P
                    t=0#让ran_infe_arr内每个感染源都被感染
    & D! Y2 [6 G4 A5 i, O+ q  M                while t<len(ran_infe_arr):#对刚才生成的会被感染的数组内的节点进行感染
    & C; A" T$ `: {' t+ X6 u! N8 S                    nodes_state[nei_arr[ran_infe_arr[t]]-1,1]=-2#标记为感染状态
    8 z" J- {8 W$ D: S                    nodes_state[nei_arr[ran_infe_arr[t]]-1,2]=temp_time+1#记录感染时间# \/ K$ `2 p4 ?$ [9 K
                        infected_array[len_arr(infected_array,nodes_num)]=nei_arr[ran_infe_arr[t]]#将此次感染节点放入总的感染节点数组中
    # x6 F: N+ t: u: P! G6 E" P6 B/ f                    g.vs[nei_arr[ran_infe_arr[t]]-1]["color"]="pink"#将此次感染的节点集的所有节点颜色置为粉色
    9 B4 U3 k" g6 O7 T& ^" V% q                    plot(g)#绘制" \* h+ {8 F% S- O# P0 t
                        t=t+15 f+ \& s5 W; C/ `0 I
                i=i+12 Q- f8 U9 b% \+ ]8 D& `+ M- u* g" d
        if temp_time>set_time-1:#当执行感染的次数等于设置的次数结束感染8 {! j/ o. c& ]' U* t8 @% @: p
            stop=True 2 `4 h0 D9 T& |' O8 [4 V
    1 O( c  N) t7 P3 V* `
    ! x  E3 G) W2 k1 a- P- b/ x3 u% F0 @
    视频演示bilibili传送门- T/ O! {7 s( m* M
    效果图
    : x, z( n5 R5 k, b5 Y
    3 B9 r6 d1 U- ^1 y# s" v9 {. h/ E( z- [) J+ z- U$ C! [
    2.jpg / E0 a. K3 J+ |3 ~$ x  T' r# A+ E

    9 M& @3 S, z2 @/ x& l! g+ b 3.png
    # I7 _* ]1 P! M$ \" {! W! I% L  @' M: r; h% Q
    4.jpg : T, y0 [1 h4 c- a) I
    * ?: [& a* V% B8 n5 [- Q
    5.png , p0 ~. H( K# X4 Q9 \7 d

    / I, R' k, X0 V# I6 a 6.png ) m8 r+ }/ D0 [. ?

    " l/ X0 Y0 ]* ^( A 7.png ————————————————
    0 k7 K  u0 \' g/ b  t版权声明:本文为CSDN博主「eck_燃」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。/ C. m; g' U" e+ X
    原文链接:https://blog.csdn.net/wdays83892469/article/details/80878862
    1 v6 f( \1 D; C- w% f& z
    ! M3 A3 Q  g* O
    0 Q& @" ]2 D: p% q$ |
    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 09:04 , Processed in 0.464819 second(s), 59 queries .

    回顶部