QQ登录

只需要一步,快速开始

 注册地址  找回密码
查看: 3100|回复: 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传播模型+ ^; L$ v/ y8 s  E4 g0 y* e- r3 ]6 \
    #SI疾病传播模型的原理
    + b5 Q- V. H3 m. R, _& a( |) s在经典的传染病模型中,种群(Population)内N个个体的状态可分为如下几类
    : t- Q" M9 ~. E; a8 h
    & g* j' y! t9 J易感状态(Susceptible)。一个个体在感染前是处于易感状态的,即该个体有可能被邻居个体感染。& o. }+ w9 ~" B* r' R2 {8 t/ M
    易感状态I(Infected)。一个感染上某种病毒的个体就称为是处于感染状态。,即该个体还会以一定概率感染其邻居个体。2 ?, A, N; R6 o6 j
    移除状态(Remove,Refractory或者Recovered)。也成为免疫状态或恢复状态,当一个个体经历过一个完整的感染周期后,该个体就不再被感染,因此就可以不再考虑改革提。
    ; A9 h$ y" {6 |+ G4 u: U, I( aSI传播模型是最简单的疾病传播模型,模型中的所有个体都只可能处于两个状态中的一个
    - i  N3 g2 w* G  g; z) W  y即易感(S)状态或感染(I)状态。SI模型中的个体一旦被感染后就永远处于感染状态。+ ~9 p% v9 }% s$ v
    在给定时刻t,令S(t)与I(t)分别代表该时刻处于易感和感染状态的个体数目,显然有
    2 ~$ [1 c- K* s+ r% m# hS(t)+I(t)恒等于N,这里,N是个体总数。随着时间t的增长,易感个体与感染个体的接触  b" g, e0 z5 ?0 i  X" ^5 P
    会导致感染个体数量的增加。加入由于个体之间的接触而导致疾病传播的概率为β,疾病仅在! Q* X4 F- [: J# W
    感染个体和易感个体之间进行接触时才会以概率β将疾病传染给易感个体。在时刻t,易感个体的比例为S(t)/N,感染个体的数量为I(t),一次,易感个体的数量将以如下变化率减少8 e  w- ~4 \! L- u* ~7 |
    ds/dt = -β*S(t)I(t)/N
    + X4 P! M7 u( I# G同时,感染个体的数量会以与易感个体相反的变化率增加,1 Q; Z- O3 p+ O' G* L& U/ B
    ds/dt = βS(t)*I(t)/N
    - D; e0 O6 q; l2 O! r) x' g分别将时刻t处于易感状态和感染状态的个体所占比例记为,/ f4 P0 u  @6 T4 `; z
    s(t)=S(t)/N
    . x9 c2 U& x6 R6 qi(t)=I(t)/N
    # O1 `  J) Y, P6 n+ a. f5 |显然有,
    $ m0 |6 f; L; y! Ts(t)+i(t)恒等于1,此时之前的公式可以记做
    7 N8 o6 Y) S2 }) dds/dt=-βsi( |; w' O6 A' ^2 J4 n; K
    di/dt=βsi
    ) X0 P" g8 X! J" f2 d* x1 z) g5 @* q' N
    di/dt=βi(1-i)* e2 a6 f- M: ~( a  ^' k! S5 j$ \
    上式也成为Logistic增长方程式(Logistic growth equation),
    3 @; Z/ Y. n6 J2 j+ _9 u# H& m5 D方程的解和图像如图
    % o' I3 e+ g4 A7 w/ V6 L 1.jpg
    & J+ A3 g; V4 |, H) B! }代码和相关文件以及环境链接:链接:https://pan.baidu.com/s/1JSfHuTPaglFimeEBLdSDyQ* P4 v, f6 M6 W/ z
    提取码:z448
    0 e- N0 L5 |6 Q2 A' n* x
      u4 K( C' y$ j. @  [4 R9 Y/ Q8 e: }) w' |
    ''': k7 q3 H+ v% O! z+ F
    实验环境Python2.7.13,igraph包,cairo包,numpy包
    7 Q3 m1 H% f2 i. Q) `  Z3 x, {'''* ~  v' M; u5 S% ~! C5 X2 \
    # -*- coding:utf8 -*
    7 m. o5 h4 G" g; n/ @from igraph import *
      a& q' g" r5 q/ v' o0 kimport numpy as numpy
    2 u) d- [) E3 q+ Rfrom  numpy import *( K- A! C; u3 |8 l! ?9 _2 r
    import random
    " U7 w  \8 c* B: ^/ p4 ?
    6 _* N9 U9 [) _, tdef len_arr(infected_array,nodes_num):#获取感染数组长度
    : a8 `6 Z& t# @0 C* n3 z6 _    len_value=0#初始化长度
    " G1 o! S$ h# m! A    len_value=nodes_num-infected_array.count(-1)#被感染数量是结点总数减去未感染节点数(未感染的结点被标记为-1)5 D' u# ]2 v* O' a3 o% I, ?6 g
        return len_value- M" u7 m, ]3 B, m( I

    . P$ P! Z1 F5 Mg=Graph.Read_GML("C:\python27\e1.gml")#将本地保存的网络数据读入变量g(生成图)
    ( b- |9 t/ Q/ d1 w* h4 Tsummary(g)
      ^" F/ l0 X2 L7 _/ S8 e$ Pnodes_num=g.vcount()#统计图中的结点个数# u3 [$ ?% w+ p
    net_mat=g.get_adjacency(type=GET_ADJACENCY_BOTH)#将网络数据转换为邻接矩阵存储在变量net_mat
    1 u" w7 k/ T$ fg.vs["color"]=["white"]#给图的顶点序列颜色赋值白色
    & w0 U" y; ]" z2 |a=[arange(nodes_num)+1]*3#声明一个N行3列的数组a5 R3 e" e' @/ `4 e4 C5 p& }: a8 N
    nodes_state=matrix(a).T#nodes_state通过转置a矩阵创建,用于存放每个节点的状态信息以及其被感染的时间(这个是理解算法的重中之重!!!)
    / ]; P8 R4 n' X3 o                                                    #第一列是节点编号,第二列是节点状态,感染状态用-2表示,第三列是节点感染的时间# A* g/ X+ z! S$ b0 o) Y
    print(nodes_state)
    ' S% h  Y7 C/ T$ f% B4 H6 V$ v1 }, m6 Uinfected_array=[-1]*34#用于存放本轮被感染的结点, 这些结点将参与下一次感染   34代表网络节点数
    , f4 f% _- D+ M0 D1 Yprint(infected_array)& Q) r" h+ U# {; [7 D4 a0 ?; _3 i

    1 H: x0 d4 q$ c  p/ \) v# P/ dinfe_rate=1#传播率(感染率) 1代表邻接点100%被感染) q- b2 `/ |+ J3 B4 u( |
    set_time=2#传播次数(感染次数) 2次6 _2 x! K' C& Y9 e' P1 e
    source_seed=1#感染源位置
    ' z) I+ ]9 M8 xnodes_state[0:nodes_num,2]=-1#给所有节点初始化感染时间为-10 E0 q' z( `4 T+ S) Z
    nodes_state[source_seed-1,1]=-2#设置第一个感染源感染状态 -2代表感染状态
    + S$ A& ~4 r' o7 _nodes_state[source_seed-1,2]=1#设置第一个感染源的感染时间为1
    0 {9 {0 h: S: ^( K) B  Gg.vs[source_seed-1]["color"]="red"#将感染的顶点颜色标红
    : D) E& B+ X5 I! ?/ iinfected_array[0]=source_seed#将感染源的位置存入被感染节点列表! K% E9 f5 T% D3 [+ k1 a
    plot(g)#绘制1 D1 w/ Q- y0 }) T

    0 ~1 U! n; U: w" d! H& \% |stop=False#感染过程结束的标记
    # D1 ~  l4 G" Y/ Jtemp_time=0#第几次感染8 Q+ R1 c% v0 O$ n% F" B4 o9 d5 h
    temp_len=0#本轮的感染源数量初始化2 s7 i. p2 N" d- I1 `
    * K. f7 T7 S" C+ w5 T
    while not stop:
    0 x$ ?' |1 Z( M+ _, y9 Q    i=0#记录让每个感染源都传播一次
    $ [% o9 S0 Y, ?. D! I    if len_arr(infected_array,nodes_num)>0 and len_arr(infected_array,nodes_num)<=nodes_num:#感染可以进行
    $ |' v4 n$ A; @) ^' G2 ~        temp_len=len_arr(infected_array,nodes_num)#获取本轮的感染源数量, Y# E4 c! H4 Y& r8 ?% v9 w' \
            while i<temp_len:
    + Q) p% V7 Y8 Y3 W7 Z            temp_time=nodes_state[infected_array-1,2]#获取每一个节点的感染时间
    1 ^' w( j5 h" j/ T            nei_count=0#下一轮可以被感染到的节点数量0 V. v- W& u7 v$ J* a
                #生成下一轮可能被感染的节点的集合nei_arr
      D! J. s: v& R# ?            for j in range(nodes_num):#遍历节点
    : X$ _6 Z. w& _% ~/ W7 t/ a                if net_mat[infected_array-1,j]==1 and nodes_state[j,1]!=-2:#是邻接节点而且未被感染
    * w! a# c2 n7 E( B                    nei_count=nei_count+1#下一轮可以被感染到的节点数量++1 K! x4 f$ b+ r+ q7 |' |; T5 z7 N
                nei_arr=[-1]*nei_count#用于临时存放本轮被感染的结点, 这些结点将参与下一次感染' u( z/ L) p& @+ {( T
                t=0( J. F; h7 Q2 ]$ N( D5 Y
                for j in range(nodes_num):/ x3 C  X! {8 u3 A" z
                    if net_mat[infected_array-1,j]==1 and nodes_state[j,1]!=-2:8 G) G) Q% b4 i$ r
                        nei_arr[t]=j+19 }4 C, o! U' [4 i" m# P
                        t=t+1
    5 Y% O+ Q% i2 F            ran_infe_arr=random.sample(range(nei_count),int(nei_count*infe_rate))#随机生成会被感染的节点的数组9 K) p. e% [" s. s/ }* u' w9 A
                                            #random.simple(arg1,num) 从arg1集合中随机取num个数据生成一个对象) T1 m/ h# Y/ l: G
                if len(ran_infe_arr)>0:#存在需要被感染的节点8 C2 H* w& c3 x2 ?8 D; o9 Y
                    t=0#让ran_infe_arr内每个感染源都被感染9 K5 I  k$ Y& x& `
                    while t<len(ran_infe_arr):#对刚才生成的会被感染的数组内的节点进行感染5 y- z! s9 U, A, B; U" Q5 m
                        nodes_state[nei_arr[ran_infe_arr[t]]-1,1]=-2#标记为感染状态& v; R1 H5 T! V8 K! N# o# M
                        nodes_state[nei_arr[ran_infe_arr[t]]-1,2]=temp_time+1#记录感染时间7 c0 Y  j& |) l* |; T
                        infected_array[len_arr(infected_array,nodes_num)]=nei_arr[ran_infe_arr[t]]#将此次感染节点放入总的感染节点数组中( C4 s* n: w$ C) R4 E
                        g.vs[nei_arr[ran_infe_arr[t]]-1]["color"]="pink"#将此次感染的节点集的所有节点颜色置为粉色
    - ?* E& ^5 y! J; T6 C& i                    plot(g)#绘制- ?2 s# M- p5 K" v2 B, [* q$ W
                        t=t+1$ }  @, s% G2 H8 t7 y
                i=i+1
    $ C2 s# a- c# o, t/ _* w    if temp_time>set_time-1:#当执行感染的次数等于设置的次数结束感染
    5 B5 o8 `2 Y" d$ y        stop=True
    * q3 m7 T" t! [2 W: \7 \, Z, L
    + i) v  \- f( H# U5 _' f: S+ x0 T( Z/ y  k3 S2 M, Q
    视频演示bilibili传送门
    " q. K. c6 t& G' r  J效果图
    5 Z. Z2 s& G0 L3 K; [: f1 e8 B! U# C( B6 B& w$ A" D
    # N3 n- W4 r% Y
    2.jpg 6 {; s7 P9 o" p/ z
    & @& S, i6 U  t* n& L) h
    3.png 1 w  [+ B2 N* g
    % }3 `( ~5 t- y3 Q9 ?, Z
    4.jpg & F5 `! c2 m# |( L! J' O$ P5 |

    ; H4 _8 m2 H- I# B+ s* | 5.png
    * t8 e2 j# Q; _: {9 b' p, u; O' e( e  T, R
    6.png * q  }; n  [* I; u6 r
    6 P# z+ ^" P3 _8 G' l, R% a
    7.png ————————————————
    * Q/ n$ t# D: u) |版权声明:本文为CSDN博主「eck_燃」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
    7 N" _  U: I9 ]原文链接:https://blog.csdn.net/wdays83892469/article/details/808788623 a: u/ n( f4 |" E; ~4 x: p

    - Y: r) ^7 K4 _  V( `
    ( N9 d" h/ K3 [. m/ O! U; C& t7 O
    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 22:47 , Processed in 0.442310 second(s), 59 queries .

    回顶部