2019-03-07 16:06:20 +00:00
|
|
|
import matplotlib.pyplot as plt
|
|
|
|
import matplotlib.colors
|
2019-03-07 15:42:41 +00:00
|
|
|
import numpy as np
|
|
|
|
import random
|
2019-03-08 14:40:50 +00:00
|
|
|
from collections import defaultdict
|
2019-03-07 15:42:41 +00:00
|
|
|
from enum import IntEnum
|
2019-03-08 14:40:50 +00:00
|
|
|
from sys import argv
|
|
|
|
from matplotlib.patches import Patch
|
2019-03-07 15:42:41 +00:00
|
|
|
|
|
|
|
|
|
|
|
class Model:
|
2019-03-08 19:29:49 +00:00
|
|
|
def __init__(self, width=50, height=50, humandens=0.15, mosquitodens=0.10,
|
|
|
|
immunepct=0.01, mosqinfpct=0.1, hm_infpct=0.5, mh_infpct=0.5,
|
|
|
|
hinfdiepct=0.01, mhungrypct=0.1, humandiepct=10**-6,
|
|
|
|
mosqdiepct=10**-3, mosqnetdens=0.00, time_steps=50000,
|
2019-03-07 20:39:11 +00:00
|
|
|
graphical=True):
|
2019-03-08 11:20:59 +00:00
|
|
|
|
2019-03-07 15:42:41 +00:00
|
|
|
self.width = width
|
|
|
|
self.height = height
|
2019-03-07 16:06:20 +00:00
|
|
|
|
2019-03-07 20:39:11 +00:00
|
|
|
# Determines if the simulation should be graphical
|
|
|
|
self.graphical = graphical
|
2019-03-07 18:19:46 +00:00
|
|
|
# The percentage of tiles that start as humans
|
2019-03-07 15:42:41 +00:00
|
|
|
self.humandens = humandens
|
2019-03-07 18:19:46 +00:00
|
|
|
# The percentage of tiles that contain mosquitos
|
2019-03-07 15:42:41 +00:00
|
|
|
self.mosquitodens = mosquitodens
|
2019-03-07 18:19:46 +00:00
|
|
|
# Percentage of humans that are immune
|
2019-03-07 15:42:41 +00:00
|
|
|
self.immunepct = immunepct
|
2019-03-07 20:27:17 +00:00
|
|
|
# Chance for a mosquito to be infectuous
|
2019-03-07 15:42:41 +00:00
|
|
|
self.mosqinfpct = mosqinfpct
|
2019-03-07 22:09:39 +00:00
|
|
|
# Chance for a mosquito to be infected by a human
|
2019-03-07 15:42:41 +00:00
|
|
|
self.hm_infpct = hm_infpct
|
2019-03-07 22:09:39 +00:00
|
|
|
# Chance for a human to be infected from a mosquito
|
2019-03-07 15:42:41 +00:00
|
|
|
self.mh_infpct = mh_infpct
|
2019-03-07 18:19:46 +00:00
|
|
|
# Chance that an infected human dies
|
2019-03-07 15:42:41 +00:00
|
|
|
self.hinfdiepct = hinfdiepct
|
2019-03-07 18:19:46 +00:00
|
|
|
# Chance for a mosquito to be hungry
|
2019-03-07 15:42:41 +00:00
|
|
|
self.mhungrypct = mhungrypct
|
2019-03-07 18:19:46 +00:00
|
|
|
# Chance for human to die from random causes
|
2019-03-07 15:42:41 +00:00
|
|
|
self.humandiepct = humandiepct
|
2019-03-07 18:19:46 +00:00
|
|
|
# Chance for a mosquito to die
|
2019-03-07 15:42:41 +00:00
|
|
|
self.mosqdiepct = mosqdiepct
|
2019-03-07 18:19:46 +00:00
|
|
|
# Percentage of tiles that contain mosquito nets
|
2019-03-07 15:42:41 +00:00
|
|
|
self.mosqnetdens = mosqnetdens
|
2019-03-07 18:19:46 +00:00
|
|
|
# The number of timesteps to run te simulation for
|
2019-03-07 15:42:41 +00:00
|
|
|
self.time_steps = time_steps
|
|
|
|
|
2019-03-08 19:29:49 +00:00
|
|
|
self.infected_trend = np.zeros(time_steps)
|
|
|
|
self.immune_trend = np.zeros(time_steps)
|
|
|
|
|
2019-03-07 18:53:26 +00:00
|
|
|
self.grid = self.gen_humans()
|
2019-03-07 15:42:41 +00:00
|
|
|
self.mosquitos = self.gen_mosquitos()
|
2019-03-07 21:07:26 +00:00
|
|
|
self.nets = self.gen_nets()
|
|
|
|
|
2019-03-07 22:09:39 +00:00
|
|
|
# statistics
|
2019-03-08 14:40:50 +00:00
|
|
|
self.stats = defaultdict(int)
|
2019-03-07 22:09:39 +00:00
|
|
|
|
2019-03-07 20:39:11 +00:00
|
|
|
if self.graphical:
|
|
|
|
self.init_draw()
|
2019-03-08 11:20:59 +00:00
|
|
|
|
2019-03-07 18:19:46 +00:00
|
|
|
def init_draw(self):
|
2019-03-07 20:39:11 +00:00
|
|
|
plt.ion()
|
2019-03-08 19:29:49 +00:00
|
|
|
plt.rcParams.update({'font.size': 18})
|
2019-03-07 18:19:46 +00:00
|
|
|
self.colors = matplotlib.colors.ListedColormap(
|
2019-03-08 14:40:50 +00:00
|
|
|
["white", "green", "red", "yellow"])
|
|
|
|
|
|
|
|
def make_babies(self, n):
|
|
|
|
if n == 0:
|
|
|
|
return
|
|
|
|
|
|
|
|
self.stats["humans born"] += n
|
|
|
|
|
|
|
|
births = np.transpose(random.sample(
|
|
|
|
list(np.transpose(np.where(self.grid == Human.DEAD))), n))
|
|
|
|
|
|
|
|
self.grid[births[0], births[1]] = \
|
|
|
|
np.random.choice((Human.HEALTHY, Human.IMMUNE), size=n,
|
|
|
|
p=(1 - self.immunepct, self.immunepct))
|
|
|
|
|
|
|
|
# Randomly distribute a net
|
|
|
|
nets = births.T[np.random.rand(len(births.T)) < self.mosqnetdens].T
|
|
|
|
self.nets[nets[0], nets[1]] = True
|
2019-03-07 15:42:41 +00:00
|
|
|
|
|
|
|
def recycle_human(self):
|
2019-03-07 22:09:39 +00:00
|
|
|
"""
|
2019-03-08 11:20:59 +00:00
|
|
|
Determine if a human dies of natural causes and then replace them by a
|
|
|
|
new human.
|
2019-03-07 22:09:39 +00:00
|
|
|
"""
|
2019-03-08 14:40:50 +00:00
|
|
|
# Find living humans, determine if they die, and if so, kill them
|
2019-03-07 18:53:26 +00:00
|
|
|
humans = np.transpose(np.where(self.grid != Human.DEAD))
|
2019-03-07 16:06:20 +00:00
|
|
|
deaths = np.random.rand(len(humans)) < self.humandiepct
|
|
|
|
|
2019-03-08 14:40:50 +00:00
|
|
|
locations = humans[deaths].T
|
|
|
|
self.grid[locations[0], locations[1]] = Human.DEAD
|
|
|
|
self.nets[locations[0], locations[1]] = False
|
2019-03-07 18:53:26 +00:00
|
|
|
|
2019-03-08 14:40:50 +00:00
|
|
|
death_count = len(np.where(deaths)[0])
|
2019-03-07 22:09:39 +00:00
|
|
|
self.stats["natural deaths"] += death_count
|
2019-03-07 16:06:20 +00:00
|
|
|
|
2019-03-08 14:40:50 +00:00
|
|
|
# Replace the dead humans
|
|
|
|
self.make_babies(death_count)
|
2019-03-07 18:19:46 +00:00
|
|
|
|
2019-03-08 19:29:49 +00:00
|
|
|
def recycle_mosquito(self):
|
|
|
|
"""
|
|
|
|
Determine if a mosquito dies of natural causes and then replace it by
|
|
|
|
a new mosquito.
|
|
|
|
"""
|
|
|
|
indices = np.random.rand(len(self.mosquitos)) < self.mosqdiepct
|
|
|
|
deaths = self.mosquitos[indices]
|
|
|
|
for mosq in deaths:
|
|
|
|
mosq.hungry = False
|
|
|
|
mosq.infected = np.random.rand() < self.mosqinfpct
|
|
|
|
mosq.x = np.random.randint(0, self.width)
|
|
|
|
mosq.y = np.random.randint(0, self.height)
|
|
|
|
|
|
|
|
self.stats["mosquito deaths"] += len(deaths)
|
|
|
|
|
2019-03-07 18:19:46 +00:00
|
|
|
def do_malaria(self):
|
|
|
|
"""
|
|
|
|
This function determines who of the infected dies from their illness
|
|
|
|
"""
|
2019-03-08 14:40:50 +00:00
|
|
|
# Find infected humans, determine if they die, and if so, kill them
|
2019-03-07 18:53:26 +00:00
|
|
|
infected = np.transpose(np.where(self.grid == Human.INFECTED))
|
2019-03-07 18:19:46 +00:00
|
|
|
deaths = np.random.rand(len(infected)) < self.hinfdiepct
|
|
|
|
|
2019-03-08 14:40:50 +00:00
|
|
|
locs = infected[deaths].T
|
|
|
|
self.grid[locs[0], locs[1]] = Human.DEAD
|
|
|
|
self.nets[locs[0], locs[1]] = False
|
2019-03-07 22:09:39 +00:00
|
|
|
|
2019-03-08 14:40:50 +00:00
|
|
|
death_count = len(np.where(deaths)[0])
|
|
|
|
self.stats["malaria deaths"] += death_count
|
|
|
|
|
|
|
|
# Replace the dead humans
|
|
|
|
self.make_babies(death_count)
|
2019-03-07 22:09:39 +00:00
|
|
|
|
|
|
|
def feed(self):
|
|
|
|
"""
|
|
|
|
Feed the mosquitos that want to and can be fed
|
|
|
|
"""
|
|
|
|
for mos in self.mosquitos:
|
|
|
|
if not mos.hungry:
|
|
|
|
continue
|
2019-03-08 14:40:50 +00:00
|
|
|
|
2019-03-07 22:09:39 +00:00
|
|
|
# state of current place on the grid where mosquito lives
|
|
|
|
state = self.grid[mos.x, mos.y]
|
|
|
|
|
2019-03-08 14:40:50 +00:00
|
|
|
if state == Human.DEAD:
|
|
|
|
continue
|
|
|
|
|
|
|
|
self.stats["mosquitos fed"] += 1
|
|
|
|
mos.hungry = False
|
|
|
|
|
|
|
|
# check if healthy human needs to be infected or mosquito
|
|
|
|
# becomes infected from eating
|
|
|
|
if state == Human.HEALTHY and mos.infected \
|
|
|
|
and random.uniform(0, 1) < self.mh_infpct:
|
|
|
|
self.grid[mos.x, mos.y] = Human.INFECTED
|
|
|
|
self.stats["humans infected"] += 1
|
|
|
|
elif state == Human.INFECTED and not mos.infected \
|
|
|
|
and random.uniform(0, 1) < self.hm_infpct:
|
|
|
|
mos.infected = True
|
|
|
|
self.stats["mosquitos infected"] += 1
|
2019-03-07 22:09:39 +00:00
|
|
|
|
|
|
|
def determine_hunger(self):
|
|
|
|
"""
|
|
|
|
Determines which mosquitos should get hungry
|
|
|
|
"""
|
|
|
|
for mos in self.mosquitos:
|
2019-03-08 11:20:59 +00:00
|
|
|
mos.hungry = not mos.hungry and \
|
|
|
|
random.uniform(0, 1) < self.mhungrypct
|
|
|
|
|
2019-03-07 22:09:39 +00:00
|
|
|
def get_movementbox(self, x: int, y: int):
|
2019-03-07 20:27:17 +00:00
|
|
|
"""
|
|
|
|
Returns indices of a moore neighbourhood around the given index
|
|
|
|
"""
|
|
|
|
|
|
|
|
x_min = (x - 1)
|
|
|
|
x_max = (x + 1)
|
|
|
|
y_min = (y - 1)
|
|
|
|
y_max = (y + 1)
|
|
|
|
|
2019-03-08 11:20:59 +00:00
|
|
|
indices = [(i % self.width, j % self.height)
|
|
|
|
for i in range(x_min, x_max + 1)
|
|
|
|
for j in range(y_min, y_max + 1)]
|
2019-03-07 20:27:17 +00:00
|
|
|
|
2019-03-07 20:31:21 +00:00
|
|
|
# remove current location from the indices
|
|
|
|
indices.remove((x, y))
|
|
|
|
|
2019-03-07 21:07:26 +00:00
|
|
|
return np.array(indices)
|
2019-03-07 20:27:17 +00:00
|
|
|
|
|
|
|
def move_mosquitos(self):
|
2019-03-07 21:07:26 +00:00
|
|
|
"""
|
|
|
|
Move the mosquitos to a new location, checks for mosquito nets
|
|
|
|
"""
|
2019-03-07 20:31:21 +00:00
|
|
|
for mosq in self.mosquitos:
|
|
|
|
# get the movement box for every mosquito
|
|
|
|
movement = self.get_movementbox(mosq.x, mosq.y)
|
2019-03-07 21:07:26 +00:00
|
|
|
|
|
|
|
# check for nets, and thus legal locations to go for the mosquito
|
2019-03-08 11:20:59 +00:00
|
|
|
legal_moves = np.where(~self.nets[tuple(movement.T)])[0]
|
|
|
|
|
2019-03-07 20:31:21 +00:00
|
|
|
# choose random new position
|
2019-03-07 21:07:26 +00:00
|
|
|
new_pos = random.choice(legal_moves)
|
2019-03-07 20:31:21 +00:00
|
|
|
|
2019-03-07 21:07:26 +00:00
|
|
|
mosq.x = movement[new_pos][0]
|
|
|
|
mosq.y = movement[new_pos][1]
|
2019-03-07 18:19:46 +00:00
|
|
|
|
2019-03-07 15:42:41 +00:00
|
|
|
def gen_humans(self):
|
2019-03-07 20:27:17 +00:00
|
|
|
"""
|
|
|
|
Fill the grid with humans that can either be healthy or infected
|
|
|
|
"""
|
2019-03-07 16:06:20 +00:00
|
|
|
# Calculate the probabilities
|
2019-03-07 15:42:41 +00:00
|
|
|
p_dead = 1 - self.humandens
|
|
|
|
p_immune = self.humandens * self.immunepct
|
2019-03-07 16:06:20 +00:00
|
|
|
p_healthy = self.humandens - p_immune
|
2019-03-07 15:42:41 +00:00
|
|
|
|
2019-03-07 16:06:20 +00:00
|
|
|
# Create the grid with humans.
|
2019-03-07 15:42:41 +00:00
|
|
|
return np.random.choice((Human.DEAD, Human.HEALTHY, Human.IMMUNE),
|
|
|
|
size=(self.width, self.height),
|
2019-03-07 16:06:20 +00:00
|
|
|
p=(p_dead, p_healthy, p_immune))
|
2019-03-07 15:42:41 +00:00
|
|
|
|
|
|
|
def gen_mosquitos(self):
|
2019-03-07 20:27:17 +00:00
|
|
|
"""
|
|
|
|
Generate the list of mosquitos
|
|
|
|
"""
|
|
|
|
|
|
|
|
mosquitos = []
|
|
|
|
|
|
|
|
count = int(self.width * self.height * self.mosquitodens)
|
|
|
|
|
|
|
|
# generate random x and y coordinates
|
|
|
|
xs = np.random.randint(0, self.width, count)
|
|
|
|
ys = np.random.randint(0, self.height, count)
|
|
|
|
coords = list(zip(xs, ys))
|
|
|
|
|
|
|
|
# generate the mosquitos
|
|
|
|
for coord in coords:
|
|
|
|
# determine if the mosquito is infected
|
|
|
|
infected = random.uniform(0, 1) < self.mosqinfpct
|
|
|
|
# determine if the mosquito starts out hungry
|
|
|
|
hungry = random.uniform(0, 1) < self.mhungrypct
|
|
|
|
mosquitos.append(Mosquito(coord[0], coord[1], infected, hungry))
|
|
|
|
|
2019-03-08 19:29:49 +00:00
|
|
|
return np.array(mosquitos)
|
2019-03-07 15:42:41 +00:00
|
|
|
|
2019-03-07 21:07:26 +00:00
|
|
|
def gen_nets(self):
|
|
|
|
"""
|
|
|
|
Generates the grid of nets
|
|
|
|
"""
|
2019-03-08 14:40:50 +00:00
|
|
|
humans = np.transpose(np.where(self.grid != Human.DEAD))
|
|
|
|
positions = humans[np.random.choice(
|
|
|
|
len(humans), size=round(self.mosqnetdens * len(humans)))].T
|
2019-03-07 21:07:26 +00:00
|
|
|
|
2019-03-08 14:40:50 +00:00
|
|
|
grid = np.zeros((self.width, self.height), dtype=bool)
|
|
|
|
grid[positions[0], positions[1]] = True
|
|
|
|
return grid
|
2019-03-07 21:07:26 +00:00
|
|
|
|
2019-03-07 15:42:41 +00:00
|
|
|
def run(self):
|
2019-03-07 20:27:17 +00:00
|
|
|
"""
|
|
|
|
This functions runs the simulation
|
|
|
|
"""
|
2019-03-08 11:20:59 +00:00
|
|
|
# Actual simulation runs inside try except to catch keyboard interrupts
|
|
|
|
# and always print stats
|
2019-03-07 22:14:48 +00:00
|
|
|
try:
|
|
|
|
for t in range(self.time_steps):
|
|
|
|
self.step()
|
2019-03-08 19:29:49 +00:00
|
|
|
|
|
|
|
total = np.count_nonzero(self.grid != Human.DEAD)
|
|
|
|
infected = np.count_nonzero(self.grid == Human.INFECTED) / \
|
|
|
|
total
|
|
|
|
immune = np.count_nonzero(self.grid == Human.IMMUNE) / total
|
|
|
|
|
|
|
|
self.infected_trend[t] = infected
|
|
|
|
self.immune_trend[t] = immune
|
|
|
|
print(f"t={t}, infected={infected:.2f}, immune={immune:.2f}",
|
|
|
|
end='\r')
|
|
|
|
|
|
|
|
if self.graphical and t % 1000 == 0:
|
2019-03-07 22:14:48 +00:00
|
|
|
self.draw(t)
|
|
|
|
except KeyboardInterrupt:
|
|
|
|
pass
|
2019-03-08 11:20:59 +00:00
|
|
|
|
2019-03-08 14:40:50 +00:00
|
|
|
print()
|
2019-03-07 22:09:39 +00:00
|
|
|
self.compile_stats()
|
|
|
|
self.print_stats()
|
2019-03-08 19:29:49 +00:00
|
|
|
self.draw_graph(t)
|
2019-03-07 22:09:39 +00:00
|
|
|
|
|
|
|
def compile_stats(self):
|
|
|
|
"""
|
|
|
|
Compiles a comprehensive list of statistics of the simulation
|
|
|
|
"""
|
2019-03-08 11:20:59 +00:00
|
|
|
self.stats["total deaths"] = \
|
|
|
|
self.stats["malaria deaths"] + self.stats["natural deaths"]
|
2019-03-08 19:29:49 +00:00
|
|
|
self.stats["final immunity"] = self.immune_trend[-1]
|
2019-03-08 11:20:59 +00:00
|
|
|
|
2019-03-07 22:09:39 +00:00
|
|
|
self.stats["net count"] = len(np.where(self.nets)[0])
|
|
|
|
|
|
|
|
def print_stats(self):
|
|
|
|
"""
|
|
|
|
Prints the gathered statistics from the simulation
|
|
|
|
"""
|
2019-03-08 14:40:50 +00:00
|
|
|
for stat, value in sorted(self.stats.items()):
|
2019-03-07 22:09:39 +00:00
|
|
|
print(f"{stat}: {self.stats[stat]}")
|
2019-03-07 15:42:41 +00:00
|
|
|
|
|
|
|
def step(self):
|
2019-03-07 20:27:17 +00:00
|
|
|
"""
|
|
|
|
Step through a timestep of the simulation
|
|
|
|
"""
|
|
|
|
# check who dies from malaria
|
|
|
|
self.do_malaria()
|
|
|
|
# check if people die from other causes
|
2019-03-07 18:53:26 +00:00
|
|
|
self.recycle_human()
|
2019-03-08 19:29:49 +00:00
|
|
|
# check if mosquitoes die
|
|
|
|
self.recycle_mosquito()
|
2019-03-07 20:27:17 +00:00
|
|
|
# move mosquitos
|
|
|
|
self.move_mosquitos()
|
2019-03-07 22:09:39 +00:00
|
|
|
# feed hungry mosquitos
|
|
|
|
self.feed()
|
|
|
|
# make mosquitos hungry again
|
|
|
|
self.determine_hunger()
|
2019-03-08 11:20:59 +00:00
|
|
|
|
2019-03-07 20:27:17 +00:00
|
|
|
def draw(self, t: int):
|
2019-03-07 22:09:39 +00:00
|
|
|
"""
|
|
|
|
Draws the grid of humans, tents and mosquitos
|
|
|
|
"""
|
2019-03-08 19:29:49 +00:00
|
|
|
plt.clf()
|
2019-03-08 14:40:50 +00:00
|
|
|
|
2019-03-07 18:19:46 +00:00
|
|
|
plt.title("t={}".format(t))
|
2019-03-08 14:40:50 +00:00
|
|
|
|
2019-03-07 20:27:17 +00:00
|
|
|
# draw the grid
|
2019-03-08 11:20:59 +00:00
|
|
|
plt.imshow(self.grid, cmap=self.colors)
|
|
|
|
|
2019-03-07 21:07:26 +00:00
|
|
|
# draw nets
|
|
|
|
net_locations = np.where(self.nets)
|
|
|
|
plt.plot(net_locations[0], net_locations[1], 'w^')
|
|
|
|
|
2019-03-07 20:27:17 +00:00
|
|
|
# draw mosquitos
|
|
|
|
for mos in self.mosquitos:
|
2019-03-08 14:40:50 +00:00
|
|
|
plt.plot(mos.y, mos.x, mos.get_color()+mos.get_shape())
|
|
|
|
|
|
|
|
# draw the legend
|
|
|
|
dead_patch = Patch(color="green", label="Healthy human")
|
|
|
|
immune_patch = Patch(color="yellow", label="Immune human")
|
|
|
|
infected_patch = Patch(color="red", label="Infected human")
|
|
|
|
plt.legend(handles=[dead_patch, immune_patch, infected_patch],
|
|
|
|
loc=9, bbox_to_anchor=(0.5, -0.03), ncol=5)
|
2019-03-07 16:06:20 +00:00
|
|
|
|
2019-03-07 15:42:41 +00:00
|
|
|
plt.pause(0.0001)
|
2019-03-08 19:29:49 +00:00
|
|
|
|
|
|
|
def draw_graph(self, t):
|
|
|
|
plt.ioff()
|
2019-03-07 15:42:41 +00:00
|
|
|
plt.clf()
|
|
|
|
|
2019-03-08 19:29:49 +00:00
|
|
|
plt.plot(np.arange(t), self.infected_trend[:t],
|
|
|
|
label="infected humans")
|
|
|
|
plt.plot(np.arange(t), self.immune_trend[:t],
|
|
|
|
label="immune humans")
|
|
|
|
|
|
|
|
plt.legend()
|
|
|
|
|
|
|
|
plt.xlabel("timestep")
|
|
|
|
plt.ylabel("prevalence")
|
|
|
|
|
|
|
|
plt.show()
|
|
|
|
|
2019-03-07 15:42:41 +00:00
|
|
|
|
|
|
|
class Mosquito:
|
|
|
|
def __init__(self, x: int, y: int, infected: bool, hungry: bool):
|
|
|
|
self.x = x
|
|
|
|
self.y = y
|
|
|
|
|
|
|
|
self.infected = infected
|
|
|
|
self.hungry = hungry
|
2019-03-08 11:20:59 +00:00
|
|
|
|
2019-03-07 20:27:17 +00:00
|
|
|
def get_color(self):
|
|
|
|
# returns the color for drawing, red if infected blue otherwise
|
|
|
|
return "r" if self.infected else "b"
|
|
|
|
|
|
|
|
def get_shape(self):
|
|
|
|
# return the shape for drawing, o if hungry + otherwise
|
|
|
|
return "o" if self.hungry else "+"
|
2019-03-07 15:42:41 +00:00
|
|
|
|
|
|
|
|
|
|
|
class Human(IntEnum):
|
|
|
|
DEAD = 0
|
|
|
|
HEALTHY = 1
|
|
|
|
INFECTED = 2
|
|
|
|
IMMUNE = 3
|
2019-03-07 22:09:39 +00:00
|
|
|
|
2019-03-07 15:42:41 +00:00
|
|
|
|
|
|
|
if __name__ == "__main__":
|
2019-03-08 14:40:50 +00:00
|
|
|
try:
|
2019-03-08 19:29:49 +00:00
|
|
|
graphical = argv[1] != "-ng"
|
2019-03-08 14:40:50 +00:00
|
|
|
except IndexError:
|
2019-03-08 19:29:49 +00:00
|
|
|
graphical = True
|
2019-03-08 14:40:50 +00:00
|
|
|
|
|
|
|
model = Model(graphical=graphical)
|
2019-03-07 20:31:21 +00:00
|
|
|
model.run()
|
2019-03-07 15:42:41 +00:00
|
|
|
|