yeet
This commit is contained in:
parent
cc15386944
commit
11d7d359da
1 changed files with 58 additions and 15 deletions
73
malaria.py
73
malaria.py
|
@ -9,10 +9,10 @@ from matplotlib.patches import Patch
|
||||||
|
|
||||||
|
|
||||||
class Model:
|
class Model:
|
||||||
def __init__(self, width=32, height=32, humandens=0.15, mosquitodens=0.10,
|
def __init__(self, width=50, height=50, humandens=0.15, mosquitodens=0.10,
|
||||||
immunepct=0.1, mosqinfpct=0.1, hm_infpct=0.5, mh_infpct=0.5,
|
immunepct=0.01, mosqinfpct=0.1, hm_infpct=0.5, mh_infpct=0.5,
|
||||||
hinfdiepct=0.01, mhungrypct=0.1, humandiepct=10**-5,
|
hinfdiepct=0.01, mhungrypct=0.1, humandiepct=10**-6,
|
||||||
mosqdiepct=10**-3, mosqnetdens=0.05, time_steps=2000,
|
mosqdiepct=10**-3, mosqnetdens=0.00, time_steps=50000,
|
||||||
graphical=True):
|
graphical=True):
|
||||||
|
|
||||||
self.width = width
|
self.width = width
|
||||||
|
@ -45,6 +45,9 @@ class Model:
|
||||||
# The number of timesteps to run te simulation for
|
# The number of timesteps to run te simulation for
|
||||||
self.time_steps = time_steps
|
self.time_steps = time_steps
|
||||||
|
|
||||||
|
self.infected_trend = np.zeros(time_steps)
|
||||||
|
self.immune_trend = np.zeros(time_steps)
|
||||||
|
|
||||||
self.grid = self.gen_humans()
|
self.grid = self.gen_humans()
|
||||||
self.mosquitos = self.gen_mosquitos()
|
self.mosquitos = self.gen_mosquitos()
|
||||||
self.nets = self.gen_nets()
|
self.nets = self.gen_nets()
|
||||||
|
@ -57,6 +60,7 @@ class Model:
|
||||||
|
|
||||||
def init_draw(self):
|
def init_draw(self):
|
||||||
plt.ion()
|
plt.ion()
|
||||||
|
plt.rcParams.update({'font.size': 18})
|
||||||
self.colors = matplotlib.colors.ListedColormap(
|
self.colors = matplotlib.colors.ListedColormap(
|
||||||
["white", "green", "red", "yellow"])
|
["white", "green", "red", "yellow"])
|
||||||
|
|
||||||
|
@ -96,6 +100,21 @@ class Model:
|
||||||
# Replace the dead humans
|
# Replace the dead humans
|
||||||
self.make_babies(death_count)
|
self.make_babies(death_count)
|
||||||
|
|
||||||
|
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)
|
||||||
|
|
||||||
def do_malaria(self):
|
def do_malaria(self):
|
||||||
"""
|
"""
|
||||||
This function determines who of the infected dies from their illness
|
This function determines who of the infected dies from their illness
|
||||||
|
@ -223,7 +242,7 @@ class Model:
|
||||||
hungry = random.uniform(0, 1) < self.mhungrypct
|
hungry = random.uniform(0, 1) < self.mhungrypct
|
||||||
mosquitos.append(Mosquito(coord[0], coord[1], infected, hungry))
|
mosquitos.append(Mosquito(coord[0], coord[1], infected, hungry))
|
||||||
|
|
||||||
return mosquitos
|
return np.array(mosquitos)
|
||||||
|
|
||||||
def gen_nets(self):
|
def gen_nets(self):
|
||||||
"""
|
"""
|
||||||
|
@ -243,22 +262,29 @@ class Model:
|
||||||
"""
|
"""
|
||||||
# Actual simulation runs inside try except to catch keyboard interrupts
|
# Actual simulation runs inside try except to catch keyboard interrupts
|
||||||
# and always print stats
|
# and always print stats
|
||||||
self.stats["humans alive before simulation"] = \
|
|
||||||
np.count_nonzero(self.grid != Human.DEAD)
|
|
||||||
try:
|
try:
|
||||||
for t in range(self.time_steps):
|
for t in range(self.time_steps):
|
||||||
print("Simulating timestep: {}".format(t), end='\r')
|
|
||||||
self.step()
|
self.step()
|
||||||
if self.graphical:
|
|
||||||
|
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:
|
||||||
self.draw(t)
|
self.draw(t)
|
||||||
except KeyboardInterrupt:
|
except KeyboardInterrupt:
|
||||||
pass
|
pass
|
||||||
self.stats["humans alive after simulation"] = \
|
|
||||||
np.count_nonzero(self.grid != Human.DEAD)
|
|
||||||
|
|
||||||
print()
|
print()
|
||||||
self.compile_stats()
|
self.compile_stats()
|
||||||
self.print_stats()
|
self.print_stats()
|
||||||
|
self.draw_graph(t)
|
||||||
|
|
||||||
def compile_stats(self):
|
def compile_stats(self):
|
||||||
"""
|
"""
|
||||||
|
@ -266,6 +292,7 @@ class Model:
|
||||||
"""
|
"""
|
||||||
self.stats["total deaths"] = \
|
self.stats["total deaths"] = \
|
||||||
self.stats["malaria deaths"] + self.stats["natural deaths"]
|
self.stats["malaria deaths"] + self.stats["natural deaths"]
|
||||||
|
self.stats["final immunity"] = self.immune_trend[-1]
|
||||||
|
|
||||||
self.stats["net count"] = len(np.where(self.nets)[0])
|
self.stats["net count"] = len(np.where(self.nets)[0])
|
||||||
|
|
||||||
|
@ -284,6 +311,8 @@ class Model:
|
||||||
self.do_malaria()
|
self.do_malaria()
|
||||||
# check if people die from other causes
|
# check if people die from other causes
|
||||||
self.recycle_human()
|
self.recycle_human()
|
||||||
|
# check if mosquitoes die
|
||||||
|
self.recycle_mosquito()
|
||||||
# move mosquitos
|
# move mosquitos
|
||||||
self.move_mosquitos()
|
self.move_mosquitos()
|
||||||
# feed hungry mosquitos
|
# feed hungry mosquitos
|
||||||
|
@ -295,8 +324,7 @@ class Model:
|
||||||
"""
|
"""
|
||||||
Draws the grid of humans, tents and mosquitos
|
Draws the grid of humans, tents and mosquitos
|
||||||
"""
|
"""
|
||||||
if t % 10 > 0:
|
plt.clf()
|
||||||
return
|
|
||||||
|
|
||||||
plt.title("t={}".format(t))
|
plt.title("t={}".format(t))
|
||||||
|
|
||||||
|
@ -319,8 +347,23 @@ class Model:
|
||||||
loc=9, bbox_to_anchor=(0.5, -0.03), ncol=5)
|
loc=9, bbox_to_anchor=(0.5, -0.03), ncol=5)
|
||||||
|
|
||||||
plt.pause(0.0001)
|
plt.pause(0.0001)
|
||||||
|
|
||||||
|
def draw_graph(self, t):
|
||||||
|
plt.ioff()
|
||||||
plt.clf()
|
plt.clf()
|
||||||
|
|
||||||
|
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()
|
||||||
|
|
||||||
|
|
||||||
class Mosquito:
|
class Mosquito:
|
||||||
def __init__(self, x: int, y: int, infected: bool, hungry: bool):
|
def __init__(self, x: int, y: int, infected: bool, hungry: bool):
|
||||||
|
@ -348,9 +391,9 @@ class Human(IntEnum):
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
try:
|
try:
|
||||||
graphical = argv[1] == "-g"
|
graphical = argv[1] != "-ng"
|
||||||
except IndexError:
|
except IndexError:
|
||||||
graphical = False
|
graphical = True
|
||||||
|
|
||||||
model = Model(graphical=graphical)
|
model = Model(graphical=graphical)
|
||||||
model.run()
|
model.run()
|
||||||
|
|
Loading…
Reference in a new issue