springer-math / Mathematics-of-Epidemics-on-Networks

Source code accompanying 'Mathematics of Epidemics on Networks' by Kiss, Miller, and Simon http://www.springer.com/us/book/9783319508047 . Documentation for the software package is at https://epidemicsonnetworks.readthedocs.io/en/latest/
MIT License
151 stars 61 forks source link

SIRV model #37

Closed debmalya191 closed 5 years ago

debmalya191 commented 5 years ago

HI @joelmiller I am trying to modify your discrete SIR model to add a vaccination parameter too. The initial population is vaccinated with prob w and then infected with prob b . There is also a control parameter Vl which is the total number of vaccinations available.

Here is my code which is heavily influenced from yours-

import networkx as nx
import random
import scipy
import EoN
from collections import defaultdict
from collections import Counter
import matplotlib.pyplot as plt
import numpy as np

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 = float('Inf'),
                return_full_data = False):

    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)

    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:
            for v in G.neighbors(u):
            ##vaccination
                if len(vaccinated)< (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

                    elif susceptible[v] and test_transmission(u,v,beta):
                        new_infecteds.add(v)
                        susceptible[v]=False

                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))
        I.append(len(infecteds))
        S.append(S[-1]-V[-1]-I[-1])
        t.append(t[-1]+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)

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.6,w=0.3,Vl=0.8)  

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

The problem I am facing is that the total number of S V I R are not coming the same as N. Also the number of people vaccinated is also always coming out to be 3 4 5 which is a very very number. Any help in this regard would be very useful to me. Thank you