From 11821b61385b255a63e72d0652d679e13a680109 Mon Sep 17 00:00:00 2001 From: AlexBocken Date: Wed, 17 May 2023 18:09:26 +0200 Subject: [PATCH] plots for linear sensitivity decay and grid pheromone decay --- main.py | 98 +++++++++++++++++++++++++++++++++++++++++++------------- model.py | 6 ++-- 2 files changed, 80 insertions(+), 24 deletions(-) diff --git a/main.py b/main.py index 1216451..4e30f8e 100755 --- a/main.py +++ b/main.py @@ -13,12 +13,23 @@ import matplotlib.pyplot as plt from mesa.space import Coordinate def main(): + check_pheromone_exponential_decay() + check_ant_sensitivity_linear_decay() + +def check_pheromone_exponential_decay(): + """ + Check whether wanted exponential decay of pheromones on grid is done correctly + shows plot of pheromone placed on grid vs. equivalent exponential decay function + """ + + from mesa.datacollection import DataCollector + width = 21 height = width - num_initial_roamers = 5 + num_initial_roamers = 0 num_max_agents = 100 nest_position : Coordinate = (width //2, height //2) - max_steps = 100 + max_steps = 1000 model = ActiveWalkerModel(width=width, height=height, num_initial_roamers=num_initial_roamers, @@ -26,28 +37,71 @@ def main(): num_max_agents=num_max_agents, max_steps=max_steps) - # just initial testing of MultiHexGrid - a = model.agent_density() - for loc in model.grid.iter_neighborhood(nest_position): - a[loc] = 3 - for agent in model.grid.get_neighbors(pos=nest_position, include_center=True): - if agent.unique_id == 2: - agent.look_for_chemical = "A" - agent.prev_pos = (9,10) - a[agent.prev_pos] = 1 - for pos in agent.front_neighbors: - a[pos] = 6 - agent.step() - print(f"{agent._next_pos=}") - agent.advance() - print(agent.front_neighbor) - a[agent.front_neighbor] = 5 + model.grid.fields["A"][5,5] = 10 + model.datacollector = DataCollector( + model_reporters={"pheromone_a": lambda m: m.grid.fields["A"][5,5] }, + agent_reporters={} + ) + model.run_model() + a_test = model.datacollector.get_model_vars_dataframe()["pheromone_a"] - print(agent.pos, agent.unique_id, agent.look_for_chemical) - neighbors = model.grid.get_neighborhood(nest_position) - print(neighbors) + import matplotlib.pyplot as plt + import numpy as np - print(a) + plt.figure() + xx = np.linspace(0,1000, 10000) + yy = a_test[0]*np.exp(-model.decay_rates["A"]*xx) + plt.plot(xx, yy, label="correct exponential function") + plt.scatter(range(len(a_test)), a_test, label="modeled decay", marker='o') + plt.title("Exponential grid pheromone decay test") + plt.legend(loc='best') + + plt.show() + + +def check_ant_sensitivity_linear_decay(): + """ + Check whether wanted linear decay of ant sensitivity is done correctly + shows plot of ant sensitivity placed on grid vs. equivalent linear decay function + not food sources are on the grid for this run to not reset sensitivities + """ + from mesa.datacollection import DataCollector + + width = 50 + height = width + num_initial_roamers = 1 + num_max_agents = 100 + nest_position : Coordinate = (width //2, height //2) + max_steps = 1000 + num_food_sources = 0 + + model = ActiveWalkerModel(width=width, height=height, + num_initial_roamers=num_initial_roamers, + nest_position=nest_position, + num_max_agents=num_max_agents, + num_food_sources=num_food_sources, + max_steps=max_steps) + + model.datacollector = DataCollector( + model_reporters={}, + agent_reporters={"sensitivity": lambda a: a.sensitivity} + ) + start = model.schedule.agents[0].sensitivity_decay_rate + model.run_model() + a_test = model.datacollector.get_agent_vars_dataframe().reset_index()["sensitivity"] + + import matplotlib.pyplot as plt + import numpy as np + + plt.figure() + xx = np.linspace(0,1000, 10000) + yy = a_test[0] - start*xx + plt.title("Linear Ant Sensitivity decay test") + plt.plot(xx, yy, label="correct linear function") + plt.scatter(range(len(a_test)), a_test, label="modeled decay", marker='o') + plt.legend(loc='best') + + plt.show() if __name__ == "__main__": diff --git a/model.py b/model.py index c88a204..a79c2a8 100644 --- a/model.py +++ b/model.py @@ -20,6 +20,8 @@ class ActiveWalkerModel(Model): def __init__(self, width : int, height : int , num_max_agents : int, num_initial_roamers : int, nest_position : Coordinate, + num_food_sources=5, + food_size=10, max_steps:int=1000) -> None: super().__init__() fields=["A", "B", "nests", "food"] @@ -41,8 +43,8 @@ class ActiveWalkerModel(Model): self.schedule.add(agent) self.grid.place_agent(agent, pos=nest_position) - for _ in range(5): - self.grid.add_food(5) + for _ in range(num_food_sources): + self.grid.add_food(food_size) self.datacollector = DataCollector( model_reporters={},