我正在制作带有增加的疫苗接种参数V的改良SIR模型。最初,图中的所有节点都容易受到感染,并且有一些最初感染的人。最初感染邻居的人首先被接种了概率w(这意味着他们不能被感染),然后又被感染了概率b。接种疫苗的总人数由V1控制,而V1是总人口的一部分。
这是我的代码-
import networkx as nx
import random
import scipy
from collections import defaultdict
from collections import Counter
import matplotlib.pyplot as plt
import numpy as np
from statistics import mean
from random import choice
from random import sample
def test_transmission(u, v, p):
return random.random()<p
def discrete_SIR(G,
initial_infecteds=None, initial_recovereds = None,beta=0.8,
rho = None, w=0.5,Vl=1,tmin = 0, tmax = 100000,
return_full_data = False):
if G.has_node(initial_infecteds):
initial_infecteds=[initial_infecteds]
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
if initial_recovereds is not None:
for u in initial_recovereds:
susceptible[u] = False
infecteds = set(initial_infecteds)
print('len of infected initially',len(infecteds))
while infecteds and t[-1]<tmax :
print('len of infected on each iter',len(infecteds))
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
#V.append(V[-1]+len(vaccinated))< (Vl*N)
#print(len(vaccinated),Vl*N)
print("HI")
print(V[-1])
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
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]
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('\n')
print('time is',str(t) +' --> ')
print('infected is',I)
print('sum is',R[-1]+V[-1]+I[-1]+S[-1])
print('R V I S',str(R[-1])+','+str(V[-1])+','+str(I[-1])+','+str(S[-1]))
print('time t[-1]',t[-1])
if not return_full_data:
return scipy.array(t), scipy.array(S),scipy.array(V), scipy.array(I), \
scipy.array(R)
m=100
G=nx.grid_2d_graph(m,m,periodic=True)
def avg_deg(self,num_nodes):
return self.number_of_edges() * 2 / num_nodes
def avg_degree(num_nodes,target_deg):
G=nx.Graph()
G.add_nodes_from(range(num_nodes))
while avg_deg(G,num_nodes) < target_deg:
n1, n2 = sample(G.nodes(), 2)
G.add_edge(n1, n2, weight=1)
nx.draw(G)
plt.show()
return G
initial_infections = [(u,v) for (u,v) in G if u==int(m/2) and v==int(m/2)]
t, S, V, I, R = discrete_SIR(G,initial_infecteds= initial_infections,beta=0.8,w=0.05,Vl=0.1)
plt.figure()
plt.plot(t,I,ls='-',color='red')
plt.plot(t,R,ls='--',color='orange')
plt.plot(t,S,ls='--',color='green')
plt.plot(t,V,ls='-',color='black')
plt.show()
我的代码存在问题,即S + V + I + R的总数应等于N,并且接种人数最多也要达到5。该数量应该更高。
答案 0 :(得分:1)
您的问题是,V仅测量该时间步中要接种的个体总数,而不是累计接种数。
所以S+I+V+R
不是常数。如果您希望V
是累计疫苗接种数,请进行V.append(V[-1]+len(vaccinated))
我不确定此测试if len(vaccinated)< (Vl*N)
是否也按照您的想法进行。它正在检查在给定的时间范围内接种疫苗的人数是否少于总人口的一部分。我怀疑您要使用累计疫苗接种数。