Модифицированная модель SIR - PullRequest
0 голосов
/ 08 июля 2019

Я делаю модифицированную модель SIR с добавленным параметром вакцинации V. Первоначально все узлы на графике восприимчивы, и есть несколько изначально инфицированных людей.Первоначально инфицированные соседи людей сначала вакцинируются с вероятностью w (что означает, что они не могут быть заражены), а затем они заражаются с помощью вируса b.Общее количество вакцинированных людей контролируется 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()

Проблема с моим кодом заключается в том, что общее число S + V + I + R должно быть равно N, а число привитых людей также составляетмаксимум должен быть 5. Он должен быть выше этого.

1 Ответ

1 голос
/ 09 июля 2019

Ваша проблема в том, что V измеряет только общее число людей, вакцинируемых за этот временной шаг, а не совокупное количество прививок.

Так что S+I+V+R не является постоянной величиной. Если вы хотите, чтобы V было совокупным числом прививок, тогда сделайте V.append(V[-1]+len(vaccinated))

Я не уверен, что этот тест if len(vaccinated)< (Vl*N) также делает то, что вы думаете. Он проверяет, меньше ли количество людей, вакцинированных за данный временной шаг, чем какая-то часть всего населения. Я подозреваю, что вы хотите использовать совокупное количество прививок.

...