【问题标题】:Visualizing modified SIR model可视化修改后的 SIR 模型
【发布时间】:2019-07-12 15:33:36
【问题描述】:

我尝试从 eon 包中修改 SIR 模型并对其进行了一些更改。它附加了一个新的疫苗接种参数,带有新的参数 beta 和 omega 以及 Vl,我的代码是-

def test_transmission(u, v, p):

return random.random()<p


def discrete_SIR(G,
            initial_infecteds,beta,
            w,Vl,return_full_data=True):

if G.has_node(initial_infecteds):
    initial_infecteds=[initial_infecteds]           

if return_full_data:
    node_history = defaultdict(lambda : ([tmin], ['S']))
    transmissions = []
    for node in initial_infecteds:
        node_history[node] = ([tmin], ['I'])
        transmissions.append((tmin-1, None, node))



node_history = defaultdict(lambda : ([tmin], ['S']))
#    transmissions = []
for node in initial_infecteds:
    node_history[node] = ([tmin], ['I'])
    #transmissions.append((tmin-1, None, node))


N=G.order()
t = [tmin]
S = [N-len(initial_infecteds)]
I = [len(initial_infecteds)]
R = [0]
V = [0]

susceptible = defaultdict(lambda: True)  
#above line is equivalent to u.susceptible=True for all nodes.

for u in initial_infecteds:
    susceptible[u] = False


infecteds = set(initial_infecteds)

while infecteds and t[-1]<tmax :
    new_infecteds = set()
    vaccinated= set()
    infector = {}  #used for returning full data.  a waste of time otherwise
    for u in infecteds:
     #   print('u-->' +str(u))
        for v in G.neighbors(u):
     #       print('v --> '+ str(v))
        ##vaccination
            if len(vaccinated)+V[-1]< (Vl*N)  : #check if vaccination over or not
                #print(len(vaccinated),Vl*N)
                #print("HI")

                if susceptible[v] and test_transmission(u, v, w): 
                    vaccinated.add(v)
                    susceptible[v] = False
     #               print('transmitting vaccination')

                elif susceptible[v] and test_transmission(u,v,beta):
                    new_infecteds.add(v)
                    susceptible[v]=False
                    infector[v] = [u]
     #               print('transmitting infection')
            else:

    #            print("BYE")
                if susceptible[v] and test_transmission(u, v,beta): 
                    new_infecteds.add(v)
                    susceptible[v] = False
                    infector[v] = [u]

           #infector[v] = [u]


    if return_full_data:
        for v in infector.keys():
            transmissions.append((t[-1], random.choice(infector[v]), v))
        next_time = t[-1]+1
        if next_time <= tmax:
            for u in infecteds:
                node_history[u][0].append(next_time)
                node_history[u][1].append('R')
            for v in new_infecteds:
                node_history[v][0].append(next_time)
                node_history[v][1].append('I')



    infecteds = new_infecteds

    R.append(R[-1]+I[-1])
    V.append(len(vaccinated)+V[-1])
    I.append(len(infecteds))
    S.append(N-V[-1]-I[-1]-R[-1])
    #S.append(S[-1]-V[-1]-I[-1])
    t.append(t[-1]+1)


print(str(R[-1])+','+str(V[-1])+','+str(I[-1])+','+str(S[-1]))  

if not return_full_data:
    return scipy.array(t), scipy.array(S), scipy.array(I), \
           scipy.array(R)
else:
    return EoN.Simulation_Investigation(G, node_history, transmissions)

现在我想在它上面运行可视化,就像在包 EON 中一样-

m=5

G=nx.grid_2d_graph(m,m,periodic=True)
initial_infections = [(u,v) for (u,v) in G if u==int(m/2) and v==int(m/2)]
sim = EoN.basic_discrete_SIR(G,0.5,initial_infecteds = initial_infections,
               return_full_data=True, tmax = 25)

pos = {node:node for node in G}
sim.set_pos(pos)
sim.display(0, node_size = 40) #display time 6
plt.show()
plt.savefig('SIR_2dgrid.png')

我需要在我的代码中进行哪些更改才能使显示功能正常工作,还是我还需要在显示功能中进行更改?

【问题讨论】:

  • 目前您需要对代码和显示功能进行修改。我希望尽快进行修改,这样就可以在您不必进行重大更改的情况下做到这一点。我稍后会尝试给出答案(目前没有时间)提供更多细节。
  • @Joel 我对我的代码做了一些更改,看起来模拟是正确的,但当然它只显示 SIR 图而不是 SIRV。我会发布我的更改,如果您能告诉我要对显示功能进行哪些更改以包含 V 参数,这将是有帮助的
  • @Joel 你有时间研究一下吗?..你也可以告诉我需要做什么..我很乐意为 EON 做出贡献。
  • 嘿 - 抱歉,我没有机会这样做。需要的第一个更改是当节点变为'V' 时,您需要为该节点更新node_history。第二个变化是 Simulation_Investigation(G, node_history, transmissions) 类的 __init__ 代码需要修改以处理节点是否为 'V',就像处理 S、I 和 R 一样。最后 _plot_ 方法将需要要修改。我希望使我编写的代码更通用,以便人们可以在任何新状态下执行此操作,但我暂时没有时间。
  • @Joel 生病尝试这样做并将其发布在这里或 github 供您查看。

标签: python numpy networkx eon


【解决方案1】:

这是我现在得到的输出:

您必须安装 EoN 版本 1.0.8rc3 或更高版本,该版本可在 github 页面上找到(请参阅 installation instructions)。目前pip 无法安装。我想确保在将其设置为pip 安装的默认值之前我没有破坏任何东西。

这是基于您的代码。你应该看看我所做的更改。 the examples I've put in the documentation 也值得一看(包括一个 SIRV 模型,其中疫苗接种规则与您所拥有的不同)。

from collections import defaultdict
import EoN
import networkx as nx
import random
import matplotlib.pyplot as plt

def test_transmission(u, v, p):
    return random.random()<p


def discrete_SIRV(G, initial_infecteds,beta,
            w,Vl,tmin=0,tmax=float('Inf'), return_full_data=True):

    if G.has_node(initial_infecteds):
        initial_infecteds=[initial_infecteds]           

    if return_full_data:
        node_history = defaultdict(lambda : ([tmin], ['S']))
        transmissions = []
        for node in initial_infecteds:
            node_history[node] = ([tmin], ['I'])
            transmissions.append((tmin-1, None, node))



    '''
    node_history = defaultdict(lambda : ([tmin], ['S']))
    #    transmissions = []
    for node in initial_infecteds:
        node_history[node] = ([tmin], ['I'])
    #transmissions.append((tmin-1, None, node))
    '''

    N=G.order()
    t = [tmin]
    S = [N-len(initial_infecteds)]
    I = [len(initial_infecteds)]
    R = [0]
    V = [0]

    susceptible = defaultdict(lambda: True)  
    #above line is equivalent to u.susceptible=True for all nodes.

    for u in initial_infecteds:
        susceptible[u] = False


    infecteds = set(initial_infecteds)

    while infecteds and t[-1]<tmax :
        new_infecteds = set()
        vaccinated= set()
        infector = {}  #used for returning full data.  a waste of time otherwise
        for u in infecteds:
            #   print('u-->' +str(u))
            for v in G.neighbors(u):
                #       print('v --> '+ str(v))
                ##vaccination
                if len(vaccinated)+V[-1]< (Vl*N)  : #check if vaccination over or not
                    #print(len(vaccinated),Vl*N)
                    #print("HI")

                    if susceptible[v] and test_transmission(u, v, w): 
                        vaccinated.add(v)
                        susceptible[v] = False

                        '''It's probably better to define a `new_vaccinated`
                        set and then do the `return_full_data` stuff later
                        where all the others are done.'''
                        if return_full_data:
                            node_history[v][0].append(t[-1]+1)
                            node_history[v][1].append('V')
     #               print('transmitting vaccination')

                    elif susceptible[v] and test_transmission(u,v,beta):
                        new_infecteds.add(v)
                        susceptible[v]=False
                        infector[v] = [u]
                        #               print('transmitting infection')
                else:

                    #            print("BYE")
                    if susceptible[v] and test_transmission(u, v,beta): 
                        new_infecteds.add(v)
                        susceptible[v] = False
                        infector[v] = [u]

                        #infector[v] = [u]


        if return_full_data:
            for v in infector.keys():
                '''This random choice is no longer needed as you've taken out 
                the possibility of multiple nodes transmitting to `v` in a given
                time step.  Now only the first one encountered does it.'''

                transmissions.append((t[-1], random.choice(infector[v]), v))
            next_time = t[-1]+1
            if next_time <= tmax:
                for u in infecteds:
                    node_history[u][0].append(next_time)
                    node_history[u][1].append('R')
                for v in new_infecteds:
                    node_history[v][0].append(next_time)
                    node_history[v][1].append('I')



        infecteds = new_infecteds

        R.append(R[-1]+I[-1])
        V.append(len(vaccinated)+V[-1])
        I.append(len(infecteds))
        S.append(N-V[-1]-I[-1]-R[-1])
        #S.append(S[-1]-V[-1]-I[-1])
        t.append(t[-1]+1)


        print(str(R[-1])+','+str(V[-1])+','+str(I[-1])+','+str(S[-1]))  

    if not return_full_data:
        return scipy.array(t), scipy.array(S), scipy.array(I), \
           scipy.array(R)
    else:
        return EoN.Simulation_Investigation(G, node_history, transmissions, possible_statuses=['S', 'I', 'R', 'V'])



print(EoN.__version__)
print("line above needs to be 1.0.8rc3 or greater or it will not work\n\n")

m=20

G=nx.grid_2d_graph(m,m,periodic=True)
initial_infections = [(u,v) for (u,v) in G if u==int(m/2) and v==int(m/2)]
beta=0.8
Vl=0.3
w=0.1

sim = discrete_SIRV(G, initial_infections, beta, w, Vl, return_full_data=True)

pos = {node:node for node in G}
sim.set_pos(pos)
sim.sim_update_colordict({'S': '#009a80','I':'#ff2000', 'R':'gray','V': '#5AB3E6'})
sim.display(6, node_size = 40) #display time 6
plt.savefig('SIRV_2dgrid.png')

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-08-18
    • 1970-01-01
    • 2021-07-22
    • 1970-01-01
    • 2018-01-14
    • 1970-01-01
    • 2020-05-09
    • 1970-01-01
    相关资源
    最近更新 更多