QQ登录

只需要一步,快速开始

 注册地址  找回密码
查看: 3098|回复: 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传播模型
    % S, q5 E( x$ s# Y0 D! x# j2 J#SI疾病传播模型的原理
    : \$ s' |! N- y, e: Z0 \! }$ `& P; l在经典的传染病模型中,种群(Population)内N个个体的状态可分为如下几类
    0 f' U9 U) t. }; f2 N
    2 G  p8 x/ a' _( Q易感状态(Susceptible)。一个个体在感染前是处于易感状态的,即该个体有可能被邻居个体感染。
    2 e2 W6 v+ ?8 i! U0 G易感状态I(Infected)。一个感染上某种病毒的个体就称为是处于感染状态。,即该个体还会以一定概率感染其邻居个体。
    ! W) Z- a. K. B: E移除状态(Remove,Refractory或者Recovered)。也成为免疫状态或恢复状态,当一个个体经历过一个完整的感染周期后,该个体就不再被感染,因此就可以不再考虑改革提。; E* J* o& X) l! z5 m
    SI传播模型是最简单的疾病传播模型,模型中的所有个体都只可能处于两个状态中的一个8 y- D1 g- n2 X% R' t8 n' @( j
    即易感(S)状态或感染(I)状态。SI模型中的个体一旦被感染后就永远处于感染状态。
    - M' K/ x, n5 |4 y; k/ z- Q在给定时刻t,令S(t)与I(t)分别代表该时刻处于易感和感染状态的个体数目,显然有
    ! \7 V( e" y8 SS(t)+I(t)恒等于N,这里,N是个体总数。随着时间t的增长,易感个体与感染个体的接触
    / A1 S- S9 ?" S/ i+ d. G会导致感染个体数量的增加。加入由于个体之间的接触而导致疾病传播的概率为β,疾病仅在8 k9 u+ t7 c* [- b! T1 l/ w
    感染个体和易感个体之间进行接触时才会以概率β将疾病传染给易感个体。在时刻t,易感个体的比例为S(t)/N,感染个体的数量为I(t),一次,易感个体的数量将以如下变化率减少; A; f8 a8 d7 m) l# G& e/ ]
    ds/dt = -β*S(t)I(t)/N
    + D6 O' B* Y' t3 l! ]2 `同时,感染个体的数量会以与易感个体相反的变化率增加,
    6 z. }! y( w& z5 h) W% [: |ds/dt = βS(t)*I(t)/N8 x5 v' B, N; K- h
    分别将时刻t处于易感状态和感染状态的个体所占比例记为,5 b: g: @5 ?  H+ h/ i) O' G2 l" r/ U
    s(t)=S(t)/N5 y; i: p5 r# G
    i(t)=I(t)/N4 ]- Y. v3 [$ e0 d* z. J
    显然有,: F7 A% f1 `$ {4 U6 W  a% V$ J" ?
    s(t)+i(t)恒等于1,此时之前的公式可以记做
    8 p5 u0 T5 L; x# rds/dt=-βsi- P) _2 Z$ Y: ^) r2 ^" W. k# G
    di/dt=βsi
    & A+ F  \. `. `7 W* g3 e
    + x: v" j& V8 c2 K4 Bdi/dt=βi(1-i)
    + l$ P( W0 h! @3 p  {上式也成为Logistic增长方程式(Logistic growth equation),+ h% m: s: T* i7 L5 t
    方程的解和图像如图
    % Y1 }  v, u* J" u$ Z 1.jpg
    ' T9 O! a- _4 K5 F+ C代码和相关文件以及环境链接:链接:https://pan.baidu.com/s/1JSfHuTPaglFimeEBLdSDyQ
    - s% I' O6 Y) c( g: k8 A6 v提取码:z448
    # p1 m# o. C7 Z" [  O" r' i+ |0 E! \% b4 N9 |. \
    " }$ J0 k5 P5 H( u1 `8 a" Q; g
    '''
      P/ F$ `* s4 ]实验环境Python2.7.13,igraph包,cairo包,numpy包
    $ P9 {# |. q( p3 B0 v! P8 X'''' x6 W/ r" k4 g/ K1 e
    # -*- coding:utf8 -*
    / K$ ^7 I7 W1 Z# O; qfrom igraph import *
    6 x- f) X4 w: ?import numpy as numpy
    - h- n2 Q( `, i1 {) Z& @from  numpy import *
    " l) K% L$ z+ F" R0 {1 dimport random
    - H; v  V/ e* u! B( ?4 f2 e4 ]& B3 G
    def len_arr(infected_array,nodes_num):#获取感染数组长度! |9 e8 p0 h# j1 U7 K2 |
        len_value=0#初始化长度# W" L/ J3 ?. g1 k5 L! o
        len_value=nodes_num-infected_array.count(-1)#被感染数量是结点总数减去未感染节点数(未感染的结点被标记为-1)$ u0 i- H, o% m8 ?& r6 y  o
        return len_value
    5 o5 F  c1 q1 |' ?( z5 |$ h" |! l5 |* P. ^) _
    g=Graph.Read_GML("C:\python27\e1.gml")#将本地保存的网络数据读入变量g(生成图)( X) s) a) M. w7 w; |' Q6 M; x4 Y' ]; ^
    summary(g)
    , p/ D: s" v5 k0 n! \nodes_num=g.vcount()#统计图中的结点个数7 ]4 o9 `0 z. p9 u
    net_mat=g.get_adjacency(type=GET_ADJACENCY_BOTH)#将网络数据转换为邻接矩阵存储在变量net_mat
    - W$ \' f% ~- \+ R0 e. fg.vs["color"]=["white"]#给图的顶点序列颜色赋值白色; [# Y2 |5 e: z  a& z" ]" i2 \. [
    a=[arange(nodes_num)+1]*3#声明一个N行3列的数组a( _1 @; F: {0 `& j5 b9 M- y+ k6 a
    nodes_state=matrix(a).T#nodes_state通过转置a矩阵创建,用于存放每个节点的状态信息以及其被感染的时间(这个是理解算法的重中之重!!!)
    " K$ I$ e7 Z: i7 M; A) h                                                    #第一列是节点编号,第二列是节点状态,感染状态用-2表示,第三列是节点感染的时间
    , ^  b5 ?' |8 t$ G0 uprint(nodes_state)0 ]- `1 I  z- F, N
    infected_array=[-1]*34#用于存放本轮被感染的结点, 这些结点将参与下一次感染   34代表网络节点数9 A2 m' J: z% M8 n1 |+ J/ y
    print(infected_array)
    0 T0 y; A- ^2 b3 K; u; E
    $ |& `; c5 D( Q( _infe_rate=1#传播率(感染率) 1代表邻接点100%被感染
    + G; C' O4 C( g' B5 X1 Qset_time=2#传播次数(感染次数) 2次
    8 ], n( F1 @% j5 S' lsource_seed=1#感染源位置
    * Z' h( D4 U" `6 w$ Y6 {/ gnodes_state[0:nodes_num,2]=-1#给所有节点初始化感染时间为-1
    , l$ [* J8 o% M% snodes_state[source_seed-1,1]=-2#设置第一个感染源感染状态 -2代表感染状态$ M. d+ \& `) O/ _3 Y5 `9 D( \
    nodes_state[source_seed-1,2]=1#设置第一个感染源的感染时间为1
    , l4 E  [' Z! B8 A0 l  vg.vs[source_seed-1]["color"]="red"#将感染的顶点颜色标红: W  o; f! [, k$ V& W8 ]
    infected_array[0]=source_seed#将感染源的位置存入被感染节点列表- r( Q. v0 W1 K8 X7 N
    plot(g)#绘制
    8 F8 J2 R+ b: f6 B! G% y, k  t0 b( S8 n
    stop=False#感染过程结束的标记9 B2 |4 H5 ?& n) @# G! {. B
    temp_time=0#第几次感染
    1 q# ]3 Q2 E( p4 L) ~3 j, u, ~temp_len=0#本轮的感染源数量初始化
    - o: i" r$ w' Y2 ?7 g: l  f
      ]( Z' g# l& ]( iwhile not stop:
    ' w% n) E  L6 y' ~5 m5 ]    i=0#记录让每个感染源都传播一次
    ; X. F6 {0 a* f9 }5 X; R; \    if len_arr(infected_array,nodes_num)>0 and len_arr(infected_array,nodes_num)<=nodes_num:#感染可以进行
    4 D: z: M8 H( ]        temp_len=len_arr(infected_array,nodes_num)#获取本轮的感染源数量% X) D/ K: o) q1 o* R/ V
            while i<temp_len:* |8 j( N2 F. T( M' _" E1 \
                temp_time=nodes_state[infected_array-1,2]#获取每一个节点的感染时间
    % s1 \% E1 N2 d- o9 I            nei_count=0#下一轮可以被感染到的节点数量
    * W0 d! B$ S; w, c9 ~! M            #生成下一轮可能被感染的节点的集合nei_arr
    9 N. O* H5 S3 J! Y. D* u            for j in range(nodes_num):#遍历节点; @2 u3 Q6 `$ _  T/ _8 x
                    if net_mat[infected_array-1,j]==1 and nodes_state[j,1]!=-2:#是邻接节点而且未被感染0 l8 Z, c# D, b6 R
                        nei_count=nei_count+1#下一轮可以被感染到的节点数量++0 Q$ o8 I0 Z2 r
                nei_arr=[-1]*nei_count#用于临时存放本轮被感染的结点, 这些结点将参与下一次感染
    5 @3 ^1 l: Q, L( {& S* a            t=02 E6 ~' a# [+ ]9 P
                for j in range(nodes_num):8 [* \/ `  p' Z! x5 E
                    if net_mat[infected_array-1,j]==1 and nodes_state[j,1]!=-2:' ^) O+ ?# F4 q- @' a5 L& ]' w
                        nei_arr[t]=j+1) d2 A, p4 \( i  N5 T6 g
                        t=t+1' L2 x! \- c2 [; q( W- s4 N
                ran_infe_arr=random.sample(range(nei_count),int(nei_count*infe_rate))#随机生成会被感染的节点的数组
    7 p- o, v- S) p: ^" s  Q, p                                        #random.simple(arg1,num) 从arg1集合中随机取num个数据生成一个对象
    + H% u8 h/ }+ {$ W! a6 i4 l            if len(ran_infe_arr)>0:#存在需要被感染的节点2 _! [4 i% B: N
                    t=0#让ran_infe_arr内每个感染源都被感染6 k7 b+ C, l* E, V9 M2 T+ @- z
                    while t<len(ran_infe_arr):#对刚才生成的会被感染的数组内的节点进行感染
    ! ?  k, c9 [) q. G; O                    nodes_state[nei_arr[ran_infe_arr[t]]-1,1]=-2#标记为感染状态, t( g. A6 l4 [/ e
                        nodes_state[nei_arr[ran_infe_arr[t]]-1,2]=temp_time+1#记录感染时间
    ) u, z) {. k6 n0 P                    infected_array[len_arr(infected_array,nodes_num)]=nei_arr[ran_infe_arr[t]]#将此次感染节点放入总的感染节点数组中+ e4 A/ x8 \" f; C4 Y% B
                        g.vs[nei_arr[ran_infe_arr[t]]-1]["color"]="pink"#将此次感染的节点集的所有节点颜色置为粉色
    $ S& Q+ h6 U7 w( |                    plot(g)#绘制
    8 H; X; I  f6 D2 J9 l, e. G3 r                    t=t+1" H1 T& C( H, V+ I+ F' X( N  S
                i=i+1) Q& O! l" V: ^* {- x
        if temp_time>set_time-1:#当执行感染的次数等于设置的次数结束感染9 r5 o+ Z+ z% e! O6 l7 y' Q& m* z
            stop=True % L: a# `$ i1 s# c- E5 S
    5 N3 p* x2 w! J2 D, T

    ; q9 B1 M! P* W9 W: f# H6 B- O视频演示bilibili传送门
    1 l- u4 P1 |/ k6 D效果图
    & K( m6 y  |( F) w3 U  q
    % F% }5 D7 Q8 h7 {. o4 A7 o/ ~3 h  I8 t3 A5 p; J0 G
    2.jpg
    ' W. o; O' _: ~% {7 ^0 x# i1 E! P. \8 k5 J1 i
    3.png 4 }4 c- f1 q. B1 @  p/ m
    3 L: J4 e8 ~1 v) l# a
    4.jpg 6 g5 Z9 h/ w8 Q2 y# h# C' Q

    3 u; q$ _8 P8 V 5.png
    1 a' Y; M4 c& M; [0 J5 N6 i' n! b, r' v" D9 M2 c; j
    6.png 3 t7 {8 N; T' e

    7 b; \$ |; e: ^+ \* P) S; u) V 7.png ————————————————
    7 J. N4 f4 w) Y2 M/ z1 X版权声明:本文为CSDN博主「eck_燃」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
    9 G* O- E6 P0 u原文链接:https://blog.csdn.net/wdays83892469/article/details/80878862
    1 c" H$ L% }+ G) g- X* }1 a+ L8 s" \8 E4 `4 W; M# v- Q
    # K6 x1 A  J9 u- c+ S- W" o+ u
    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 18:51 , Processed in 0.836192 second(s), 58 queries .

    回顶部