QQ登录

只需要一步,快速开始

 注册地址  找回密码
查看: 3096|回复: 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传播模型. z# `% K7 e" f  o$ |1 {
    #SI疾病传播模型的原理
    % Q4 D2 y+ m( _4 z) L0 i, }4 S在经典的传染病模型中,种群(Population)内N个个体的状态可分为如下几类
    6 x- x% J; T: n0 y0 [4 D! s2 S5 G' Y; S
    易感状态(Susceptible)。一个个体在感染前是处于易感状态的,即该个体有可能被邻居个体感染。1 t+ c* w  b% H: l) n+ R) b5 }
    易感状态I(Infected)。一个感染上某种病毒的个体就称为是处于感染状态。,即该个体还会以一定概率感染其邻居个体。
    4 C' `" ]2 N, G" ]" V1 X* m移除状态(Remove,Refractory或者Recovered)。也成为免疫状态或恢复状态,当一个个体经历过一个完整的感染周期后,该个体就不再被感染,因此就可以不再考虑改革提。
    & r9 \1 Q0 R. T4 s! G5 Z4 o- A' u  ~6 iSI传播模型是最简单的疾病传播模型,模型中的所有个体都只可能处于两个状态中的一个
    2 h/ M2 {, T4 i) ?3 s4 y即易感(S)状态或感染(I)状态。SI模型中的个体一旦被感染后就永远处于感染状态。
    5 r5 B, C9 q4 s" O. B4 Q1 a" u在给定时刻t,令S(t)与I(t)分别代表该时刻处于易感和感染状态的个体数目,显然有' N0 C' g, M0 K4 p
    S(t)+I(t)恒等于N,这里,N是个体总数。随着时间t的增长,易感个体与感染个体的接触
    $ x2 N5 H8 B8 g3 |/ G会导致感染个体数量的增加。加入由于个体之间的接触而导致疾病传播的概率为β,疾病仅在3 y$ S; t+ r- ~( W# j
    感染个体和易感个体之间进行接触时才会以概率β将疾病传染给易感个体。在时刻t,易感个体的比例为S(t)/N,感染个体的数量为I(t),一次,易感个体的数量将以如下变化率减少6 ^5 c$ y% x6 E- e% j2 _2 [* M
    ds/dt = -β*S(t)I(t)/N
    2 b4 ^  H$ w& C- z+ M& n同时,感染个体的数量会以与易感个体相反的变化率增加," F% L+ p! }/ k
    ds/dt = βS(t)*I(t)/N8 h( {3 R/ E( V) e7 }+ b
    分别将时刻t处于易感状态和感染状态的个体所占比例记为,: D. p: ^) ]9 Z- M
    s(t)=S(t)/N: `  k! L& E, v6 ?2 _8 F
    i(t)=I(t)/N  [9 L# v1 T( t6 z  B
    显然有,
    % j3 W4 k6 P3 p; js(t)+i(t)恒等于1,此时之前的公式可以记做5 D/ z3 R* j% j. |
    ds/dt=-βsi; w: g% m8 b( X1 e4 v
    di/dt=βsi6 i5 X# L. k  Y- p& Q# N. Z* W$ v
    1 U" E! K  }/ P: f1 G2 D
    di/dt=βi(1-i)
    $ S8 T/ U* m, T1 k' v; {$ v上式也成为Logistic增长方程式(Logistic growth equation),
    / h5 a- L- x  K) \( E方程的解和图像如图
    " \5 r7 \3 S% B/ G' j4 e 1.jpg
    ) }4 i, J( V3 `$ R  z' u代码和相关文件以及环境链接:链接:https://pan.baidu.com/s/1JSfHuTPaglFimeEBLdSDyQ
    ( l2 |$ G3 {4 n" |. ?+ r提取码:z4488 S) }% T  o* A7 Q1 J: F
    ' M9 `- [) h2 J7 H
    1 ?* p9 w7 R' ^& |* Z& t; q2 C
    '''
    & U" x1 D0 k8 X9 g7 R3 i; T' S实验环境Python2.7.13,igraph包,cairo包,numpy包
    9 O$ }; J! c  T'''
    * [% B5 y: P+ r' U1 p& y# -*- coding:utf8 -*
    , h/ {( A1 G2 {from igraph import *
    ' Z/ {' w3 y' _- g7 M. oimport numpy as numpy; j' e, q2 g+ F0 i* }' v/ `
    from  numpy import *
      d0 N6 W4 n1 ~* himport random, h6 A& d% t9 O% C  o
    " p$ _" A: P. j+ B! n( t
    def len_arr(infected_array,nodes_num):#获取感染数组长度
    $ U5 J, N9 V6 P    len_value=0#初始化长度$ t. ~! M! A+ x) U
        len_value=nodes_num-infected_array.count(-1)#被感染数量是结点总数减去未感染节点数(未感染的结点被标记为-1)
    1 {3 X! A  Y& Q7 a  n0 a6 }    return len_value
    # I# I2 f( Q/ k2 D3 }
    # o9 h& f0 R: ~4 C$ l) V+ Ug=Graph.Read_GML("C:\python27\e1.gml")#将本地保存的网络数据读入变量g(生成图)3 N5 d; i" d/ R, S5 \
    summary(g)
    2 Q- B% ?& v- U* r, Pnodes_num=g.vcount()#统计图中的结点个数, V& s! ]! }3 b9 o. |3 C9 ~# K
    net_mat=g.get_adjacency(type=GET_ADJACENCY_BOTH)#将网络数据转换为邻接矩阵存储在变量net_mat
      {, Q( W2 q) j) Cg.vs["color"]=["white"]#给图的顶点序列颜色赋值白色
    ' z# V% v+ V0 t, Q5 b" Ea=[arange(nodes_num)+1]*3#声明一个N行3列的数组a
    3 v) J3 }. e/ o+ E) o0 A+ ^nodes_state=matrix(a).T#nodes_state通过转置a矩阵创建,用于存放每个节点的状态信息以及其被感染的时间(这个是理解算法的重中之重!!!)
    3 B/ a& A, k- c& l$ s) I                                                    #第一列是节点编号,第二列是节点状态,感染状态用-2表示,第三列是节点感染的时间' ~9 m- d3 A" h7 q, A% u9 Q
    print(nodes_state)" z/ T4 i/ [. v- O; C, u0 s, c3 \
    infected_array=[-1]*34#用于存放本轮被感染的结点, 这些结点将参与下一次感染   34代表网络节点数4 ~4 Q% l5 u3 R
    print(infected_array)
    ' `  D7 A" ?& Q$ L9 F$ J
    2 x0 X% u3 u0 i4 X) ]infe_rate=1#传播率(感染率) 1代表邻接点100%被感染7 D( C0 j2 v, P% D7 X( `
    set_time=2#传播次数(感染次数) 2次
    1 Q4 t/ J# l. z/ u# z9 o5 Tsource_seed=1#感染源位置& a" t8 G+ T0 b/ R
    nodes_state[0:nodes_num,2]=-1#给所有节点初始化感染时间为-14 m+ k# k% e! N
    nodes_state[source_seed-1,1]=-2#设置第一个感染源感染状态 -2代表感染状态
    3 F2 {0 m# C& E" E4 \# o! E* _nodes_state[source_seed-1,2]=1#设置第一个感染源的感染时间为1
    # c. V8 j  j+ A1 u3 i- Hg.vs[source_seed-1]["color"]="red"#将感染的顶点颜色标红0 x( M7 M$ d' g/ w6 z1 R$ ?: W
    infected_array[0]=source_seed#将感染源的位置存入被感染节点列表( ^3 q: V! ?* p6 _) g* z; U
    plot(g)#绘制$ R! Y8 k7 D1 H$ ~$ ]

    & u0 w+ m4 J" B8 _* @stop=False#感染过程结束的标记
    4 g. w8 I' |$ ztemp_time=0#第几次感染2 B0 ?. ^. y) f. W0 Y% g4 p5 w# n) T
    temp_len=0#本轮的感染源数量初始化$ Z2 c9 b& T, R: D2 c& s; V* k

    0 y! y" S3 {, {, Q" nwhile not stop:
    $ \2 @( ]" O7 o9 E2 h& {    i=0#记录让每个感染源都传播一次+ A8 }( w- T% A% Y5 c- m8 ?
        if len_arr(infected_array,nodes_num)>0 and len_arr(infected_array,nodes_num)<=nodes_num:#感染可以进行$ S; j. ]% s, |( z" B
            temp_len=len_arr(infected_array,nodes_num)#获取本轮的感染源数量
    , w' m# H$ Q: e  `# O        while i<temp_len:
    ) s" ]# {$ h  F! l            temp_time=nodes_state[infected_array-1,2]#获取每一个节点的感染时间
    / T% {' |! A% h            nei_count=0#下一轮可以被感染到的节点数量
    1 O% F. V" [& N/ r% g0 o            #生成下一轮可能被感染的节点的集合nei_arr
    3 O: c: [4 j6 p1 J( j% u; K! x            for j in range(nodes_num):#遍历节点
    " F6 B' K7 w* B  R) k. v                if net_mat[infected_array-1,j]==1 and nodes_state[j,1]!=-2:#是邻接节点而且未被感染& ]: F( L2 I9 t3 K2 I+ ~4 o
                        nei_count=nei_count+1#下一轮可以被感染到的节点数量++& C0 W& }/ h1 |/ Y* z& F2 n# r! {: _
                nei_arr=[-1]*nei_count#用于临时存放本轮被感染的结点, 这些结点将参与下一次感染" L0 G# B% ]' Y) z# z9 U
                t=0
    & c) l) @" a0 t7 A! l/ d            for j in range(nodes_num):
    ( k& r3 r  L* X& {                if net_mat[infected_array-1,j]==1 and nodes_state[j,1]!=-2:
    ) {; Z4 B! v' `8 D0 w                    nei_arr[t]=j+15 ]: S+ r( ]  M; q( s2 Z9 C
                        t=t+1
    ( [  q5 B) l$ I% n1 _0 l            ran_infe_arr=random.sample(range(nei_count),int(nei_count*infe_rate))#随机生成会被感染的节点的数组5 m1 t& [8 A7 l
                                            #random.simple(arg1,num) 从arg1集合中随机取num个数据生成一个对象5 `# ]. z: h. |; G9 [& k
                if len(ran_infe_arr)>0:#存在需要被感染的节点
    2 {' i  T: H8 i! W( p                t=0#让ran_infe_arr内每个感染源都被感染
    6 a* F( f4 X: Y8 W3 j$ W                while t<len(ran_infe_arr):#对刚才生成的会被感染的数组内的节点进行感染
    0 D$ ^2 p+ V7 |( [  m0 X7 G                    nodes_state[nei_arr[ran_infe_arr[t]]-1,1]=-2#标记为感染状态9 p) X1 |0 J; Y$ U. o0 i$ ]
                        nodes_state[nei_arr[ran_infe_arr[t]]-1,2]=temp_time+1#记录感染时间7 W$ [/ @0 t, E" r- |( d
                        infected_array[len_arr(infected_array,nodes_num)]=nei_arr[ran_infe_arr[t]]#将此次感染节点放入总的感染节点数组中
    ! H3 V! y: J/ ^) B                    g.vs[nei_arr[ran_infe_arr[t]]-1]["color"]="pink"#将此次感染的节点集的所有节点颜色置为粉色
    " v2 F8 S4 b- x+ `# V% T                    plot(g)#绘制) J) _7 {% P/ T1 n/ y/ `+ Y! j
                        t=t+1  t9 y& i5 N/ Z* I* p3 ~, x# L
                i=i+1$ U/ |4 N# [( n( C) X1 ^
        if temp_time>set_time-1:#当执行感染的次数等于设置的次数结束感染
    1 K# ~" h! A9 s1 M' o( Q        stop=True - c0 i& P' _# i! C6 ~. x0 K
    & T4 L7 ]! A0 a& U9 v

      o+ m: ^' {+ `5 \! [视频演示bilibili传送门* G0 p* I; S$ x
    效果图) p% i; t  U( V& N6 H( K

    7 {5 l7 T4 O1 R
    ' l; a% a5 i! d2 x: F; W8 } 2.jpg 7 h# H, p# Z/ R1 _4 @& @, l

    + M2 z: W" C) B' P- R) W 3.png
    + [4 R" \9 e4 g# a/ p! u$ I  ^0 l' b  a7 \) Q% u
    4.jpg " d% @9 S( K9 w( H  p* W
      V* U4 P! M: f2 y
    5.png 7 u0 z' H) \7 k) ?3 y; h% b
    - }1 k! q  }! s: L
    6.png
    ) g0 X( t% M1 h% L7 ^5 D  T
    # u- P; h+ N8 O) m6 ^5 } 7.png ————————————————# k  O% d* r* L5 ?# U
    版权声明:本文为CSDN博主「eck_燃」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。5 @. P$ L- j! z, U
    原文链接:https://blog.csdn.net/wdays83892469/article/details/80878862  ^. M" d1 H3 Y3 b" P, i
    : @! A5 M- O0 b6 ?8 x$ D7 r
    9 V' u/ i, `0 c  p/ T6 r3 W
    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 16:26 , Processed in 0.556785 second(s), 59 queries .

    回顶部