QQ登录

只需要一步,快速开始

 注册地址  找回密码
查看: 3153|回复: 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传播模型
    9 c0 C+ m0 q! E! D, N#SI疾病传播模型的原理1 Z% `9 \0 D& W% D
    在经典的传染病模型中,种群(Population)内N个个体的状态可分为如下几类9 L# b" y, ^2 N3 D" s
    3 T8 v# v' j: d; d
    易感状态(Susceptible)。一个个体在感染前是处于易感状态的,即该个体有可能被邻居个体感染。2 j( S" }# Z; n
    易感状态I(Infected)。一个感染上某种病毒的个体就称为是处于感染状态。,即该个体还会以一定概率感染其邻居个体。
    2 {1 ]' j5 f% L7 X. ^% \移除状态(Remove,Refractory或者Recovered)。也成为免疫状态或恢复状态,当一个个体经历过一个完整的感染周期后,该个体就不再被感染,因此就可以不再考虑改革提。
    * F! S, m3 V3 J* I$ \6 {SI传播模型是最简单的疾病传播模型,模型中的所有个体都只可能处于两个状态中的一个" h% R7 }) _7 ?! f. n
    即易感(S)状态或感染(I)状态。SI模型中的个体一旦被感染后就永远处于感染状态。
      S# w' o6 r: q, |9 ^在给定时刻t,令S(t)与I(t)分别代表该时刻处于易感和感染状态的个体数目,显然有" \  ]  ]; ]4 S! S  u/ v4 B
    S(t)+I(t)恒等于N,这里,N是个体总数。随着时间t的增长,易感个体与感染个体的接触7 C6 M  y& U- `  }2 w- _
    会导致感染个体数量的增加。加入由于个体之间的接触而导致疾病传播的概率为β,疾病仅在
    & r1 O8 e5 J- @$ F4 y感染个体和易感个体之间进行接触时才会以概率β将疾病传染给易感个体。在时刻t,易感个体的比例为S(t)/N,感染个体的数量为I(t),一次,易感个体的数量将以如下变化率减少' |6 L# F8 Q' q8 D& q: x6 i5 {
    ds/dt = -β*S(t)I(t)/N
    + X$ j* L. t) M; H$ N1 {同时,感染个体的数量会以与易感个体相反的变化率增加,
    7 G9 k! N' v6 v, ^$ ~' h% `) |" @& b0 nds/dt = βS(t)*I(t)/N7 \2 U- B; S- C2 F' \% h- J" G
    分别将时刻t处于易感状态和感染状态的个体所占比例记为,
    0 B% j0 p/ A) E6 r5 u% Is(t)=S(t)/N
    4 T; R8 r0 @$ P9 di(t)=I(t)/N
    # t( k' y0 S" f8 _, ?显然有,7 p$ [/ ~0 i& B8 S. g* E
    s(t)+i(t)恒等于1,此时之前的公式可以记做
    3 o' |  w* R6 ?+ kds/dt=-βsi
    8 ^9 a' P% Z' U9 E; F( o% n) |di/dt=βsi
    . _3 T1 t$ a( C+ T, U9 Y7 }4 l9 z
    $ P+ T2 q5 n' Y% k9 f2 ]di/dt=βi(1-i)# E; e' l# V- y  R$ H" y$ f9 l
    上式也成为Logistic增长方程式(Logistic growth equation),0 n9 l- i! Z* W/ O  n, t; E
    方程的解和图像如图
    - Q9 f: f. [7 q+ }1 N0 N 1.jpg 0 V/ ], R2 \2 c% z; c" o. m6 Q: I2 W/ ^
    代码和相关文件以及环境链接:链接:https://pan.baidu.com/s/1JSfHuTPaglFimeEBLdSDyQ7 A: f3 Y2 \; q2 h
    提取码:z448/ F! l- _. Z3 G+ p

    $ g: l: t* Q' T* v# j* b% j4 r# n7 ?& M5 |7 K
    '''
    3 H9 P" I- y; E% B$ R; h5 }( S& K实验环境Python2.7.13,igraph包,cairo包,numpy包) h4 ~- ^. W/ S9 h$ T2 Q
    '''
    " X8 p. U  S! p! U/ ]5 B7 I# -*- coding:utf8 -** d$ H  f# s6 s
    from igraph import */ I4 S; `, g  z: W
    import numpy as numpy
    3 H, u7 j9 h( k1 p" l* r0 |0 @from  numpy import *
    ! B  T2 O3 T6 W: ^; Timport random
    % Q* q$ _* D( Z6 l! i; @8 Z
    & C7 i8 V6 s2 n5 g! mdef len_arr(infected_array,nodes_num):#获取感染数组长度" U, ?3 Q- O. L4 T4 w* v6 b
        len_value=0#初始化长度0 l9 ]! |8 ]% I* e: q
        len_value=nodes_num-infected_array.count(-1)#被感染数量是结点总数减去未感染节点数(未感染的结点被标记为-1)! ]) h: A- t% g# j  K
        return len_value7 i. w% \  u1 t; M$ Y. w

    + `4 W3 }% c) Z( n' u; Fg=Graph.Read_GML("C:\python27\e1.gml")#将本地保存的网络数据读入变量g(生成图)4 a9 u9 `6 r; o+ U9 i) |$ d
    summary(g)1 a, J" M/ y  b
    nodes_num=g.vcount()#统计图中的结点个数
    ' [% ?$ t. o% @0 fnet_mat=g.get_adjacency(type=GET_ADJACENCY_BOTH)#将网络数据转换为邻接矩阵存储在变量net_mat
    % C3 g5 Z: a. m* C$ _g.vs["color"]=["white"]#给图的顶点序列颜色赋值白色
    # a; y; J! V3 @, Y' C- `a=[arange(nodes_num)+1]*3#声明一个N行3列的数组a8 X* `2 e: S1 t5 ~! p. W  x8 o
    nodes_state=matrix(a).T#nodes_state通过转置a矩阵创建,用于存放每个节点的状态信息以及其被感染的时间(这个是理解算法的重中之重!!!)5 i5 d8 ]9 `- C/ U& s0 J
                                                        #第一列是节点编号,第二列是节点状态,感染状态用-2表示,第三列是节点感染的时间
    % T; Q5 F6 Q1 p2 Jprint(nodes_state)* f% O( Q2 V  I. _0 h0 o
    infected_array=[-1]*34#用于存放本轮被感染的结点, 这些结点将参与下一次感染   34代表网络节点数
    7 g* w* [: }( f7 }4 S: [1 f+ aprint(infected_array)
    9 z1 l% E7 L) k. F, C
    - q8 f* P4 M0 _! vinfe_rate=1#传播率(感染率) 1代表邻接点100%被感染" n# o+ n, s! T' `4 Q+ C
    set_time=2#传播次数(感染次数) 2次
    0 M& t2 }, j: b' i( Nsource_seed=1#感染源位置
    # ^' n& e. h; F  g& f1 bnodes_state[0:nodes_num,2]=-1#给所有节点初始化感染时间为-1$ o$ X: Y: [7 U
    nodes_state[source_seed-1,1]=-2#设置第一个感染源感染状态 -2代表感染状态' @1 \: |( @6 ^7 @
    nodes_state[source_seed-1,2]=1#设置第一个感染源的感染时间为1
    7 P5 x. s* u: T* X5 qg.vs[source_seed-1]["color"]="red"#将感染的顶点颜色标红
    & ~6 |+ Y/ t# a$ \- Z. z* R+ Hinfected_array[0]=source_seed#将感染源的位置存入被感染节点列表
      V+ U  H* c( W( Y# ]( i2 F# s% ~plot(g)#绘制9 m( [8 u4 b$ [5 B
    5 I2 |: u+ ?3 R" p: w) g
    stop=False#感染过程结束的标记! R% P6 y0 g# a: Z
    temp_time=0#第几次感染
      o  p& w" }3 p# V) ^temp_len=0#本轮的感染源数量初始化
    ! y4 I' K6 B  J# T
    # K! }% C0 I+ I$ N9 F8 i8 ]while not stop:
    % W8 J0 [+ O! W4 k; p- K7 k    i=0#记录让每个感染源都传播一次
    8 j, C2 ~; J' \5 W1 ^    if len_arr(infected_array,nodes_num)>0 and len_arr(infected_array,nodes_num)<=nodes_num:#感染可以进行
    $ K* x# Q( n! p/ e; Q        temp_len=len_arr(infected_array,nodes_num)#获取本轮的感染源数量
    % K" o; e( e5 I) H6 g+ a        while i<temp_len:
    7 I  ~! _$ l3 j) U            temp_time=nodes_state[infected_array-1,2]#获取每一个节点的感染时间
    9 D/ A, G! H0 C3 I7 I  r) q+ \; M            nei_count=0#下一轮可以被感染到的节点数量. K/ R  i. X7 k0 {% S
                #生成下一轮可能被感染的节点的集合nei_arr
    9 f. _: k5 S& E& P* @            for j in range(nodes_num):#遍历节点$ |6 ]" S) o, a( }+ |* r: P
                    if net_mat[infected_array-1,j]==1 and nodes_state[j,1]!=-2:#是邻接节点而且未被感染
    ' ^3 I5 m& V% O  L                    nei_count=nei_count+1#下一轮可以被感染到的节点数量++
    " F4 q8 b' j: |            nei_arr=[-1]*nei_count#用于临时存放本轮被感染的结点, 这些结点将参与下一次感染
    ! D! Q, B. z3 ?            t=0
    # O+ i! _5 r/ \' R9 w5 G! P            for j in range(nodes_num):
    & M9 Z  _/ @2 c7 R' ]" q                if net_mat[infected_array-1,j]==1 and nodes_state[j,1]!=-2:
    9 B1 o  \' z+ U  J- ]5 U                    nei_arr[t]=j+1+ F, P$ a6 i* w( w/ P5 H5 t! F" A
                        t=t+1
    ! [6 V8 D" y( f            ran_infe_arr=random.sample(range(nei_count),int(nei_count*infe_rate))#随机生成会被感染的节点的数组3 A3 u8 a' m3 [- ]+ j
                                            #random.simple(arg1,num) 从arg1集合中随机取num个数据生成一个对象) S+ V9 N4 ^2 I  l
                if len(ran_infe_arr)>0:#存在需要被感染的节点
    0 X4 y; r% y2 v& x, w$ W' }  D/ x                t=0#让ran_infe_arr内每个感染源都被感染% y) `+ m7 y. R% O/ g( I6 P) B
                    while t<len(ran_infe_arr):#对刚才生成的会被感染的数组内的节点进行感染
    / E3 P; O8 n+ s2 Y& }% Q                    nodes_state[nei_arr[ran_infe_arr[t]]-1,1]=-2#标记为感染状态; ]1 ~5 Z! `. T& F2 `! d( w$ n- e
                        nodes_state[nei_arr[ran_infe_arr[t]]-1,2]=temp_time+1#记录感染时间
    ; j1 `# I- B9 Y( t                    infected_array[len_arr(infected_array,nodes_num)]=nei_arr[ran_infe_arr[t]]#将此次感染节点放入总的感染节点数组中
    8 W. I6 ?/ E3 v2 c9 T                    g.vs[nei_arr[ran_infe_arr[t]]-1]["color"]="pink"#将此次感染的节点集的所有节点颜色置为粉色# K# @: L0 Y* [) n+ i& `
                        plot(g)#绘制3 T; i7 g0 T- I3 s% a
                        t=t+11 g5 ?1 a) a  q6 I4 m# h8 X
                i=i+1; n7 Z$ t* v  D( F- M
        if temp_time>set_time-1:#当执行感染的次数等于设置的次数结束感染, E# r4 r( K$ A; a5 H- {4 ]
            stop=True ) \+ X. Q' [+ s3 T

    : |' T. d  ]- g
    2 E; D1 P1 c3 s% D8 x视频演示bilibili传送门4 E1 k1 ~& _3 ]5 N
    效果图8 ^# a- r! j% d  p8 u9 ]
    8 E( t; {9 V5 H+ ~8 o  R

      W( h' m* T. _  E! N 2.jpg 7 H7 F$ S2 \% n2 \" C
    2 P+ ^4 E" h; ?4 \
    3.png / [' |7 N1 W* A3 V
    $ e) v& I) w& p0 M$ \1 B; i/ Y$ ]
    4.jpg 7 s3 ]1 k* v7 |* X9 A9 y5 ]
    6 v3 C7 a1 m' _. j) t! @  J
    5.png " J, |3 w9 ?. ?3 G; g6 @- ~3 S

    6 l3 j3 y0 i& [ 6.png 8 v: @: Z; t8 n, Q1 e2 q% i! A

    : V3 q' Q2 v9 G5 K2 U$ R3 I9 h3 z 7.png ————————————————% H" e$ }; K; ~2 b0 j: K  u, r2 m, Y1 ?
    版权声明:本文为CSDN博主「eck_燃」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
    + [* [1 G- a9 n) i% I2 k原文链接:https://blog.csdn.net/wdays83892469/article/details/80878862
    9 I: i6 b; Z0 S% i+ O6 Y
    2 t6 i, r" |  E* P' }! W5 q# A- O! [  f' L
    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-9-11 11:20 , Processed in 0.424396 second(s), 59 queries .

    回顶部