QQ登录

只需要一步,快速开始

 注册地址  找回密码
查看: 3152|回复: 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传播模型; ?4 [0 F/ [( L) ?) N
    #SI疾病传播模型的原理
    ! A) g+ l5 L! p$ p在经典的传染病模型中,种群(Population)内N个个体的状态可分为如下几类; h- i! s7 t) I1 H$ }' f

    / l2 X* @) R) `4 L/ `易感状态(Susceptible)。一个个体在感染前是处于易感状态的,即该个体有可能被邻居个体感染。- V( w' H! s0 P% Q$ M
    易感状态I(Infected)。一个感染上某种病毒的个体就称为是处于感染状态。,即该个体还会以一定概率感染其邻居个体。; |6 w8 @4 r# G6 P' u# X* q
    移除状态(Remove,Refractory或者Recovered)。也成为免疫状态或恢复状态,当一个个体经历过一个完整的感染周期后,该个体就不再被感染,因此就可以不再考虑改革提。" T+ b' k2 L3 I. x* L& G; T: A/ D
    SI传播模型是最简单的疾病传播模型,模型中的所有个体都只可能处于两个状态中的一个! [; |. c4 [; V  z7 o  d7 J1 j
    即易感(S)状态或感染(I)状态。SI模型中的个体一旦被感染后就永远处于感染状态。4 s1 e/ m) v8 c2 e+ I0 H
    在给定时刻t,令S(t)与I(t)分别代表该时刻处于易感和感染状态的个体数目,显然有3 c; d6 Y# ^9 W. V
    S(t)+I(t)恒等于N,这里,N是个体总数。随着时间t的增长,易感个体与感染个体的接触
    0 a6 Y& N% [+ V: @会导致感染个体数量的增加。加入由于个体之间的接触而导致疾病传播的概率为β,疾病仅在( v# P1 {( K) g' L- ~( ~/ i
    感染个体和易感个体之间进行接触时才会以概率β将疾病传染给易感个体。在时刻t,易感个体的比例为S(t)/N,感染个体的数量为I(t),一次,易感个体的数量将以如下变化率减少
    * p5 l2 i$ C  D& ?ds/dt = -β*S(t)I(t)/N1 \3 i) X" w, N! m# e5 |* D
    同时,感染个体的数量会以与易感个体相反的变化率增加,
    $ l% P; K2 Y1 K% A" Cds/dt = βS(t)*I(t)/N9 T* s- p4 h9 t8 ]$ R) i
    分别将时刻t处于易感状态和感染状态的个体所占比例记为,
    ( t4 Z3 C, {8 ^2 w$ Ss(t)=S(t)/N
    : @( [% g- K, u# pi(t)=I(t)/N
    + ^. |4 _6 v2 r显然有,
    + ?2 k! _) @# d% E" is(t)+i(t)恒等于1,此时之前的公式可以记做, b8 c/ G) z3 Z' B4 z" P* U* C
    ds/dt=-βsi
    + B3 G& W; @* r; m5 U$ ndi/dt=βsi
    % W) c( L6 M; |8 `, U7 Y* ^; V7 [+ F/ ?* h5 r
    di/dt=βi(1-i)0 L# i* P! g. X7 d/ I) Q0 L& q
    上式也成为Logistic增长方程式(Logistic growth equation),
    9 N* `4 Q& Y- e% `0 j3 C5 G方程的解和图像如图8 B& u4 M6 I* }4 F6 [# n
    1.jpg / z* A, L. R2 _$ b4 }
    代码和相关文件以及环境链接:链接:https://pan.baidu.com/s/1JSfHuTPaglFimeEBLdSDyQ* s) {  H0 _+ Y4 b5 b1 u
    提取码:z448( p, Y2 }2 I- T! i, T& r4 k- L: L" B

    & n2 x- h" V$ r+ b; x: P" [) V' ]3 M, `! [! s; O$ P4 |: S+ u
    '''  m5 n( w( P, x
    实验环境Python2.7.13,igraph包,cairo包,numpy包2 N+ J: R. \% O( l& Z: A
    '''! G# f( C+ W# P  w
    # -*- coding:utf8 -*
    ! q  p, A* s" C2 L- t2 a. _  a2 T. Ifrom igraph import *' T  h  y+ U' f; B: ~: ~: _* ?
    import numpy as numpy/ d+ x  @' V7 Q. R: @* e4 W
    from  numpy import *
    " z% Z' v1 V: D' B0 e* Q7 simport random
    ; l5 F, j) w  `: c3 ]1 z5 \5 L) n2 E# d9 W$ q* A/ |8 a
    def len_arr(infected_array,nodes_num):#获取感染数组长度
    % F& R$ y/ ?, O) f% O5 n. J1 a0 z    len_value=0#初始化长度
    6 C  `, @8 w3 Q  Y+ f# z9 H    len_value=nodes_num-infected_array.count(-1)#被感染数量是结点总数减去未感染节点数(未感染的结点被标记为-1)
    & a" R1 U: ]# n+ |. ~  B& K6 o' o    return len_value
    & z/ I- r3 S/ q- e6 u1 T9 W
    ' d8 [- v9 H  A) U( ng=Graph.Read_GML("C:\python27\e1.gml")#将本地保存的网络数据读入变量g(生成图)# _6 a# Q# A/ _
    summary(g)
    # t- F! i1 L# s% u) mnodes_num=g.vcount()#统计图中的结点个数/ k3 @4 z7 P: U7 P
    net_mat=g.get_adjacency(type=GET_ADJACENCY_BOTH)#将网络数据转换为邻接矩阵存储在变量net_mat
    ! {" F5 C% d. ^0 ^3 T* g+ `2 Fg.vs["color"]=["white"]#给图的顶点序列颜色赋值白色0 Z0 E. f- l6 {8 I! @! o4 [, d  o
    a=[arange(nodes_num)+1]*3#声明一个N行3列的数组a
    $ g) e* Z4 @5 {nodes_state=matrix(a).T#nodes_state通过转置a矩阵创建,用于存放每个节点的状态信息以及其被感染的时间(这个是理解算法的重中之重!!!)
    ! A9 ]  Z: `+ _/ W9 a* E  X                                                    #第一列是节点编号,第二列是节点状态,感染状态用-2表示,第三列是节点感染的时间
    ' e8 b! e+ x# H- O4 e7 Bprint(nodes_state), ^7 h% Y! Z/ J5 T2 b
    infected_array=[-1]*34#用于存放本轮被感染的结点, 这些结点将参与下一次感染   34代表网络节点数
    9 m, x$ L& r' v, Xprint(infected_array)
      L  j, v( \$ y0 p% j
    % K% S0 }4 `- `8 |infe_rate=1#传播率(感染率) 1代表邻接点100%被感染
    8 t5 e- D/ {  y5 |set_time=2#传播次数(感染次数) 2次3 z9 s* M5 \+ ]' Q& B4 W  X
    source_seed=1#感染源位置
    ) |2 a  x  y; d9 d, C9 hnodes_state[0:nodes_num,2]=-1#给所有节点初始化感染时间为-1
    9 p- `  k: G. a& h9 U$ w& Z2 Enodes_state[source_seed-1,1]=-2#设置第一个感染源感染状态 -2代表感染状态* S6 f" ~; m) B9 K( E- \+ h' E* N
    nodes_state[source_seed-1,2]=1#设置第一个感染源的感染时间为1
    3 N$ l- g  I4 z% h1 z" ig.vs[source_seed-1]["color"]="red"#将感染的顶点颜色标红* I* n  r9 u* x" b
    infected_array[0]=source_seed#将感染源的位置存入被感染节点列表
    1 [6 H, B& @* P8 h1 ~1 P0 cplot(g)#绘制  q+ a% z4 _/ @3 }, F2 `( G
    : P4 z- O% Z$ H
    stop=False#感染过程结束的标记
    - C1 b6 D( ?5 b( Z: Atemp_time=0#第几次感染; I8 A+ w% s2 ?( V
    temp_len=0#本轮的感染源数量初始化: r" z) u) g; m8 \9 l$ F& Y
    ' l4 F$ u1 z( s9 y# r( T
    while not stop:! D# E) ^7 T: D$ x8 N
        i=0#记录让每个感染源都传播一次# Q; t% k- ~) T
        if len_arr(infected_array,nodes_num)>0 and len_arr(infected_array,nodes_num)<=nodes_num:#感染可以进行! P0 `$ ^0 L" h. q
            temp_len=len_arr(infected_array,nodes_num)#获取本轮的感染源数量% ?' Z2 s4 a( z7 Z1 Z6 `
            while i<temp_len:
    ' D) M% ]3 R$ Q7 i+ a% N            temp_time=nodes_state[infected_array-1,2]#获取每一个节点的感染时间+ s+ r& q& u7 O4 a2 |
                nei_count=0#下一轮可以被感染到的节点数量
    5 s, ~( A8 z8 F+ U7 i* j0 i            #生成下一轮可能被感染的节点的集合nei_arr
    . b6 f, P" y# Q/ O: c            for j in range(nodes_num):#遍历节点" w& c' ?6 s, X9 c; c0 i
                    if net_mat[infected_array-1,j]==1 and nodes_state[j,1]!=-2:#是邻接节点而且未被感染
    " c$ R1 C$ V  h6 U# U% N                    nei_count=nei_count+1#下一轮可以被感染到的节点数量++
    7 i6 Q) P  V* ^/ A' w. ]            nei_arr=[-1]*nei_count#用于临时存放本轮被感染的结点, 这些结点将参与下一次感染
    - X6 ]* u% S; s( A# h* }            t=0: u( z, H& ?# L: o% [2 _) I* b7 |
                for j in range(nodes_num):
    ( b: Q/ i7 F6 Q  I                if net_mat[infected_array-1,j]==1 and nodes_state[j,1]!=-2:1 q" x' s6 P1 X/ \! s
                        nei_arr[t]=j+1
    2 o4 J/ x3 n" `* v                    t=t+1
    3 C% a( m) c8 h6 Q5 y/ n9 W            ran_infe_arr=random.sample(range(nei_count),int(nei_count*infe_rate))#随机生成会被感染的节点的数组
    4 V/ c2 J& V, d* v                                        #random.simple(arg1,num) 从arg1集合中随机取num个数据生成一个对象
    * d/ s6 x9 p( ~3 o4 o( T3 z            if len(ran_infe_arr)>0:#存在需要被感染的节点
    6 k. r: {/ [9 w* E. P! m4 K" o                t=0#让ran_infe_arr内每个感染源都被感染
    7 n9 w7 r/ R$ ]. [" A; u9 E                while t<len(ran_infe_arr):#对刚才生成的会被感染的数组内的节点进行感染' s6 X  w! _. f( K8 t' m- k( A
                        nodes_state[nei_arr[ran_infe_arr[t]]-1,1]=-2#标记为感染状态1 ]* M% Y9 N' @5 M' v5 H
                        nodes_state[nei_arr[ran_infe_arr[t]]-1,2]=temp_time+1#记录感染时间
    3 p; c; {. V# g8 y$ W4 W3 U& B                    infected_array[len_arr(infected_array,nodes_num)]=nei_arr[ran_infe_arr[t]]#将此次感染节点放入总的感染节点数组中5 j' I. Y. ^3 E
                        g.vs[nei_arr[ran_infe_arr[t]]-1]["color"]="pink"#将此次感染的节点集的所有节点颜色置为粉色0 H' D. X  u: a, ?* ~. I
                        plot(g)#绘制
    % {$ L& {6 T& d1 o% ?8 s: F                    t=t+1
    - W/ Q7 W( e0 A  C" W+ b            i=i+1
    8 a( J9 ?: a) ^2 F( ]/ Y    if temp_time>set_time-1:#当执行感染的次数等于设置的次数结束感染7 C  w; M3 V1 x% o4 a5 g
            stop=True
    9 Z% }1 O4 F) V
    / `. @" E4 [6 \' R0 ^4 g- a' I6 X
    3 F' U0 H3 e2 h5 }$ o! d0 i视频演示bilibili传送门; O/ |) I9 `% m, E5 B
    效果图7 c% e) h! X4 D  n0 U

      L  j- P$ ^  b1 o* f- E
    ! `" ~$ I; h) J5 a' W- v5 n( B! K 2.jpg # Y( Z  D: V) n2 {

    2 b  D+ ]& B" @# W- h- ~ 3.png
    ( v" z/ A6 t# z
    - r- l5 k/ F6 h0 ]) L  ~9 K$ p 4.jpg - A3 o) |6 h+ \# G3 u) e5 V0 d
    . C4 `+ I& Y9 d1 _; Y
    5.png
    9 w9 w& ?; J% A3 _5 c/ J9 o. ]) z; o$ R1 w
    6.png $ E" H* @% W1 y3 |3 V1 ?
    ; K' E$ K( Y7 s% e8 i
    7.png ————————————————% b. D; N+ o' t: @/ ~6 _
    版权声明:本文为CSDN博主「eck_燃」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。7 X, a& y" O- N+ o. J$ S
    原文链接:https://blog.csdn.net/wdays83892469/article/details/808788627 j2 j# ]  t0 Y" }

    / t. Q/ j0 Y5 W% Q' p* V$ Z! N! l7 @5 m
    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-10 16:39 , Processed in 1.793148 second(s), 58 queries .

    回顶部