QQ登录

只需要一步,快速开始

 注册地址  找回密码
查看: 1731|回复: 1
打印 上一主题 下一主题

Python实现简单的SI传播模型

[复制链接]
字体大小: 正常 放大
杨利霞        

5250

主题

81

听众

16万

积分

  • 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传播模型' X$ h  a1 h$ z( D7 J9 h3 d7 z
    #SI疾病传播模型的原理0 d/ N2 O6 o. X4 S5 E* K' f( E* v
    在经典的传染病模型中,种群(Population)内N个个体的状态可分为如下几类* s! z) l7 f$ W5 t
      O/ \9 {$ V8 E7 T3 C' N
    易感状态(Susceptible)。一个个体在感染前是处于易感状态的,即该个体有可能被邻居个体感染。
    + e# l% j0 o4 Y易感状态I(Infected)。一个感染上某种病毒的个体就称为是处于感染状态。,即该个体还会以一定概率感染其邻居个体。
    + v. G) e. @& Z9 @: Q移除状态(Remove,Refractory或者Recovered)。也成为免疫状态或恢复状态,当一个个体经历过一个完整的感染周期后,该个体就不再被感染,因此就可以不再考虑改革提。
    / X, k, ~, v1 V$ {+ f, C, T7 X4 ?SI传播模型是最简单的疾病传播模型,模型中的所有个体都只可能处于两个状态中的一个' q4 ]# Q* {! I& T9 N# O0 f. [- H
    即易感(S)状态或感染(I)状态。SI模型中的个体一旦被感染后就永远处于感染状态。% d/ Y, D! b* g6 f+ g* }( Z
    在给定时刻t,令S(t)与I(t)分别代表该时刻处于易感和感染状态的个体数目,显然有
    - N  x) \( ]3 J2 MS(t)+I(t)恒等于N,这里,N是个体总数。随着时间t的增长,易感个体与感染个体的接触
    % |: D' r$ R5 I% U. F# ^会导致感染个体数量的增加。加入由于个体之间的接触而导致疾病传播的概率为β,疾病仅在% _, X1 c5 u7 X  V2 ~4 u1 Q; f
    感染个体和易感个体之间进行接触时才会以概率β将疾病传染给易感个体。在时刻t,易感个体的比例为S(t)/N,感染个体的数量为I(t),一次,易感个体的数量将以如下变化率减少
    # z" k  B  u; D" m- ^ds/dt = -β*S(t)I(t)/N
    $ }5 P- v7 k0 w& a9 x! [同时,感染个体的数量会以与易感个体相反的变化率增加,, K; {6 ]& i: d+ `+ h3 q* i1 a1 |
    ds/dt = βS(t)*I(t)/N
    & r0 V  O  m, L0 z$ \分别将时刻t处于易感状态和感染状态的个体所占比例记为,% B- W8 C. g, J+ x% R4 S2 {
    s(t)=S(t)/N* L; c2 q8 F* `3 M8 |1 L
    i(t)=I(t)/N
    ; O3 w$ A. U2 J' E: F0 t" E7 N显然有,- M! a" e2 ?1 G: }% z3 ~2 _1 |8 V+ z! g
    s(t)+i(t)恒等于1,此时之前的公式可以记做& t: g6 `8 a4 L- U8 l
    ds/dt=-βsi
    4 E6 U8 ]2 d$ i7 Fdi/dt=βsi% }: H) t! @0 }! H- f- ~0 R# Q

    : `7 {/ u) @5 g! S3 D" `2 M# Vdi/dt=βi(1-i)5 Q# a% {# D# q% C3 n5 Y. W
    上式也成为Logistic增长方程式(Logistic growth equation),+ |! |) {1 e1 A
    方程的解和图像如图; [3 m3 F4 C( |9 W
    1.jpg 8 w' `0 L% ]. d# g" J, D3 n
    代码和相关文件以及环境链接:链接:https://pan.baidu.com/s/1JSfHuTPaglFimeEBLdSDyQ4 d3 e5 u- g4 l3 }7 \
    提取码:z448
    % a/ ]) X3 F9 q( |" Z: V5 s0 A1 K0 u8 C5 F) P8 `. W

    ' ^3 r& D# J: ~5 r3 N  z9 z; v- _'''2 C, {) _# j) }/ i) u- D+ v1 w& R
    实验环境Python2.7.13,igraph包,cairo包,numpy包5 J+ H+ K# i1 {5 y, ~* O8 O0 u1 D
    '''
    . x  n1 g2 G" y$ i* Q, l- z# -*- coding:utf8 -*4 a' @, E; d5 E8 ~  |6 w
    from igraph import *
    ; D! k! B3 U/ j  F. n& Cimport numpy as numpy
    9 F! h2 {# E7 n3 i0 G8 ]2 b6 jfrom  numpy import *
    - R# z4 [3 [. I7 ~import random
    ! f) ~3 n% d% _8 a7 Z
    " a7 w. I6 p8 b  ?def len_arr(infected_array,nodes_num):#获取感染数组长度2 O4 R2 X- b. }2 p& W3 U% p
        len_value=0#初始化长度
    3 Y$ K& _5 G( O2 B* }; M3 J  q    len_value=nodes_num-infected_array.count(-1)#被感染数量是结点总数减去未感染节点数(未感染的结点被标记为-1)
    1 d7 l9 U( p6 v+ D( }2 Q% e' I    return len_value
    7 e8 m6 e: D: ]* [6 P
    / E. L' ^! q- E7 f8 ^g=Graph.Read_GML("C:\python27\e1.gml")#将本地保存的网络数据读入变量g(生成图)
    . P% m, e1 B/ a$ v% r! c& @summary(g)
    " O/ _! H( w- v+ anodes_num=g.vcount()#统计图中的结点个数
    1 C- d# u+ J/ ]/ I* }: xnet_mat=g.get_adjacency(type=GET_ADJACENCY_BOTH)#将网络数据转换为邻接矩阵存储在变量net_mat
    4 C' `" B/ I+ p1 L8 o5 E. ^g.vs["color"]=["white"]#给图的顶点序列颜色赋值白色
    : f/ J; ~  g% k2 R! k2 w4 Y5 ]a=[arange(nodes_num)+1]*3#声明一个N行3列的数组a  [3 u' C- x) u$ R& }# f
    nodes_state=matrix(a).T#nodes_state通过转置a矩阵创建,用于存放每个节点的状态信息以及其被感染的时间(这个是理解算法的重中之重!!!)0 N% Y6 X4 N" I1 d
                                                        #第一列是节点编号,第二列是节点状态,感染状态用-2表示,第三列是节点感染的时间
    # K# Y. o: y1 M7 _/ u2 y: W  `) }print(nodes_state)
    7 j! q4 h/ n, V! C& ^infected_array=[-1]*34#用于存放本轮被感染的结点, 这些结点将参与下一次感染   34代表网络节点数
    % P9 J7 [* K: U, R8 E8 p- pprint(infected_array)
    - T  W" e  O  m) C" I( B) L
    : U+ l; h9 p% v) \% G: f4 minfe_rate=1#传播率(感染率) 1代表邻接点100%被感染
    $ Q! i+ T; n3 a, y2 Y' |set_time=2#传播次数(感染次数) 2次: U: q3 z/ b$ k0 D
    source_seed=1#感染源位置
    ' m# k* Q. ~& ]. c+ F9 Bnodes_state[0:nodes_num,2]=-1#给所有节点初始化感染时间为-1& q# I9 x# d( s6 Q/ T+ Q" i
    nodes_state[source_seed-1,1]=-2#设置第一个感染源感染状态 -2代表感染状态
    7 B: X8 K) A- h; P( d8 G9 qnodes_state[source_seed-1,2]=1#设置第一个感染源的感染时间为17 U- T. m5 D, W0 ~" U
    g.vs[source_seed-1]["color"]="red"#将感染的顶点颜色标红: W2 }2 i  {" a  M9 @/ _" U* X
    infected_array[0]=source_seed#将感染源的位置存入被感染节点列表* V. I, w! ]' i. }8 p5 y+ K" e
    plot(g)#绘制
    : e% k6 P* P) Y3 B7 M- |
    $ l/ Q* R3 |1 w) X; L: Qstop=False#感染过程结束的标记
    & Q6 y* N( d4 B$ v0 c4 ftemp_time=0#第几次感染
    ! ?+ P' Y; t' [7 L2 z% y- e, itemp_len=0#本轮的感染源数量初始化- U6 |) z( o$ q$ \8 C
    ) {! d$ Q5 D% [9 }0 @
    while not stop:7 M+ z4 H. P! j( T/ ?; ~* [6 J% ~
        i=0#记录让每个感染源都传播一次4 ^  B5 X0 A6 \! E! O3 a
        if len_arr(infected_array,nodes_num)>0 and len_arr(infected_array,nodes_num)<=nodes_num:#感染可以进行" }7 m) k0 n' B# T+ ^: Z! {  _9 o
            temp_len=len_arr(infected_array,nodes_num)#获取本轮的感染源数量
    8 c% M. {. I3 ^4 c: {, a        while i<temp_len:& C- W# ]5 l0 K5 d! V0 v, C  s
                temp_time=nodes_state[infected_array-1,2]#获取每一个节点的感染时间
    ' r+ H3 |& y( g7 t  ^            nei_count=0#下一轮可以被感染到的节点数量$ t: g. t) E* i# q! `+ h0 n* b
                #生成下一轮可能被感染的节点的集合nei_arr
    & A& E( H' H0 g& [; P( @            for j in range(nodes_num):#遍历节点
    3 g5 {9 q6 h) q6 u. u7 T& a  r                if net_mat[infected_array-1,j]==1 and nodes_state[j,1]!=-2:#是邻接节点而且未被感染4 G8 A' W4 D/ z9 N  t
                        nei_count=nei_count+1#下一轮可以被感染到的节点数量++
    + S* ^: a1 R4 J8 @1 W8 e            nei_arr=[-1]*nei_count#用于临时存放本轮被感染的结点, 这些结点将参与下一次感染
    : _" ]% b9 d# M( ]: T& K- m            t=0
    9 y3 W; O! H4 H7 Y# E  G            for j in range(nodes_num):
    7 {1 i# a! g- ?8 t8 M: I& ~, X                if net_mat[infected_array-1,j]==1 and nodes_state[j,1]!=-2:; w( r  ^% t6 ]  j9 Z( ]& m3 ^
                        nei_arr[t]=j+1
    + F8 ]" O6 Q" W6 M                    t=t+12 t0 g- I4 A6 b. H7 w: O
                ran_infe_arr=random.sample(range(nei_count),int(nei_count*infe_rate))#随机生成会被感染的节点的数组
    ( e3 ~0 @( F; x                                        #random.simple(arg1,num) 从arg1集合中随机取num个数据生成一个对象- B% J2 |5 r- O, ?, q
                if len(ran_infe_arr)>0:#存在需要被感染的节点
    4 Z5 g+ i( z; e, u0 b                t=0#让ran_infe_arr内每个感染源都被感染5 P$ T9 T3 c4 X; ]7 |
                    while t<len(ran_infe_arr):#对刚才生成的会被感染的数组内的节点进行感染
    + y! @- I/ K' n. r# Q                    nodes_state[nei_arr[ran_infe_arr[t]]-1,1]=-2#标记为感染状态
    . |% o+ E% p$ E# F2 }, r                    nodes_state[nei_arr[ran_infe_arr[t]]-1,2]=temp_time+1#记录感染时间! o  O8 e9 i7 }- m  ^" J
                        infected_array[len_arr(infected_array,nodes_num)]=nei_arr[ran_infe_arr[t]]#将此次感染节点放入总的感染节点数组中& C  f! K, z  x" X# C3 q5 Y8 u
                        g.vs[nei_arr[ran_infe_arr[t]]-1]["color"]="pink"#将此次感染的节点集的所有节点颜色置为粉色
    % y% }( b- h& c2 ?, @' _                    plot(g)#绘制  H8 Z3 f3 g3 }
                        t=t+1  _4 m; g8 @# s& Q3 h4 s* N
                i=i+1
    6 I& K  X* ^* K    if temp_time>set_time-1:#当执行感染的次数等于设置的次数结束感染
    4 g( z% m4 v4 J% q# U: D$ ]. A; E        stop=True , S0 e: V4 C, K5 ?  l' O4 k% B

    ' U/ y9 K9 X. P' v; N. |: U+ H* f/ j' b
    视频演示bilibili传送门
    6 X8 g: p/ N. `+ e8 m' \+ L" R$ H效果图: \% f' d+ v8 ]- p1 w/ v
    * S6 r# o1 Z* B  M2 M" p/ {2 p

    4 C) U; f. h+ m0 n* p 2.jpg   h* v  [# y* @* C3 q

    4 {1 P+ v8 d1 a% I9 |6 I 3.png * V0 v( i8 W8 Z* X0 m% r
    + h4 p) h! ~3 A1 a% q; M$ V. |) P0 [
    4.jpg
    ; i/ l2 a) q1 s% |2 o+ J  A
    9 f3 b2 z$ }+ s2 k. S 5.png
    # a+ f  j. e6 q- Q+ @5 ^. S, h% M5 G3 x3 _+ `: Y+ x5 E1 x' O
    6.png
    9 l9 u8 T% c) g8 J
    1 w; O, v3 r3 E; [1 s+ V1 H$ r 7.png ————————————————  P3 z+ h4 @5 W9 x" E$ y% E
    版权声明:本文为CSDN博主「eck_燃」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
    * n: S3 Q1 i! d4 h原文链接:https://blog.csdn.net/wdays83892469/article/details/80878862; K3 j  C9 W  h5 k& f/ t6 V5 Q6 g
    / E+ _$ T; x! V7 c( N
    7 k3 c, S5 a5 L8 H! x% L% 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, 2024-4-27 12:31 , Processed in 0.303185 second(s), 58 queries .

    回顶部