Python 改进的SIR模型

Python 改进的SIR模型,python,numpy,graph,networkx,eon,Python,Numpy,Graph,Networkx,Eon,我正在制作一个修改的SIR模型,添加了一个疫苗接种参数V。最初,图中的所有节点都是易受感染的,并且有一些最初感染的人。最初被感染的人首先接种prob-w(这意味着他们不能被感染),然后感染prob-b。接种疫苗的总人数由Vl控制,Vl只占总人口的一小部分 这是我的密码- import networkx as nx import random import scipy from collections import defaultdict from collections import Count

我正在制作一个修改的SIR模型,添加了一个疫苗接种参数V。最初,图中的所有节点都是易受感染的,并且有一些最初感染的人。最初被感染的人首先接种prob-w(这意味着他们不能被感染),然后感染prob-b。接种疫苗的总人数由Vl控制,Vl只占总人口的一小部分

这是我的密码-

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()
将networkx导入为nx
随机输入
进口西皮
从集合导入defaultdict
从收款进口柜台
将matplotlib.pyplot作为plt导入
将numpy作为np导入
从统计数据看进口意味着什么
从随机进口选择
来自随机进口样品
def测试_变速箱(u、v、p):

return random.random()您的问题是,V只测量在该时间步长内接种疫苗的总人数,而不是累计接种次数

所以
S+I+V+R
不是常数。如果希望
V
为累计接种数,则执行
V.append(V[-1]+len(已接种))


如果len(接种疫苗)<(Vl*N)
也在做你认为应该做的事,我不确定这个测试是否也在做。它正在检查在给定的时间步长内接种疫苗的人数是否少于整个人口的一部分。我怀疑你想使用累计接种数

I
有多大?@Joel它取决于当前的w,b Vl,它最多变化一次200@Joel你现在能检查一下吗?我做了你说的更改,但是模型仍然显示出奇怪的行为。什么是奇怪的?(顺便说一句,我在上面加了一个标签‘eon’,因为我想开始收集相关问题——如果你能在将来的eon问题上使用这个标签,那就太好了)谢谢!…我意识到了错误