vivianes changes

This commit is contained in:
Alexander Bocken 2023-06-26 10:23:19 +02:00
parent 8f2771463d
commit 15efd64c3e
Signed by: Alexander
GPG Key ID: 1D237BE83F9B05E8
3 changed files with 151 additions and 5 deletions

View File

@ -17,6 +17,7 @@ import numpy.typing as npt
from mesa.agent import Agent from mesa.agent import Agent
from mesa.space import Coordinate from mesa.space import Coordinate
class RandomWalkerAnt(Agent): class RandomWalkerAnt(Agent):
def __init__(self, unique_id, model, def __init__(self, unique_id, model,
look_for_pheromone=None, look_for_pheromone=None,
@ -127,12 +128,13 @@ class RandomWalkerAnt(Agent):
self.sensitivity = self.model.s_0 self.sensitivity = self.model.s_0
self.energy = self.model.e_0 self.energy = self.model.e_0
self.look_for_pheromone = "A" # Is this a correct interpretation? self.look_for_pheromone = "B"
self.drop_pheromone = "A" self.drop_pheromone = "A"
self._prev_pos = neighbor self._prev_pos = neighbor
self._next_pos = self.pos self._next_pos = self.pos
# recruit new ants # recruit new ants
for agent_id in self.model.get_unique_ids(self.model.N_r): for agent_id in self.model.get_unique_ids(self.model.N_r):
if self.model.schedule.get_agent_count() < self.model.N_m: if self.model.schedule.get_agent_count() < self.model.N_m:

96
main.py Executable file → Normal file
View File

@ -1,3 +1,4 @@
#!/bin/python #!/bin/python
""" """
main.py - Part of ants project main.py - Part of ants project
@ -14,7 +15,7 @@ import matplotlib.pyplot as plt
from mesa.space import Coordinate from mesa.space import Coordinate
from mesa.datacollection import DataCollector from mesa.datacollection import DataCollector
from multihex import MultiHexGrid #from multihex import MultiHexGrid
def main(): def main():
pass pass
@ -213,3 +214,96 @@ This program is distributed in the hope that it will be useful, but WITHOUT ANY
You should have received a copy of the GNU Affero General Public License along with this program. If not, see <https://www.gnu.org/licenses/> You should have received a copy of the GNU Affero General Public License along with this program. If not, see <https://www.gnu.org/licenses/>
""" """
# |%%--%%| <Z5Ra4Us5kN|y6CRYNrY9x>
# Access the DataCollector
datacollector = model.datacollector
# |%%--%%| <y6CRYNrY9x|v2PfrSWbzG>
# Get the data from the DataCollector
model_data = datacollector.get_model_vars_dataframe()
# |%%--%%| <v2PfrSWbzG|74OaeOltqi>
print(model_data.columns)
# |%%--%%| <74OaeOltqi|WpQLCA0RuP>
# Plot the number of alive ants over time
plt.plot(model_data.index, model_data['alive_ants'])
plt.xlabel('Time')
plt.ylabel('Number of Alive Ants') #this should probably be "active" ants, since it is not considering those in the nest
plt.title('Number of Alive Ants Over Time')
plt.grid(True)
plt.show()
# |%%--%%| <WpQLCA0RuP|UufL3yaROS>
# Plot the number of sucessful walkers over time
plt.plot(model_data.index, model_data['sucessful_walkers'])
plt.xlabel('Time')
plt.ylabel('Number of Sucessful Walkers')
plt.title('Number of Sucessful Walkers Over Time')
plt.grid(True)
plt.show()
# |%%--%%| <UufL3yaROS|mgJWQ0bqG1>
# Calculate the cumulative sum
model_data['cumulative_sucessful_walkers'] = model_data['sucessful_walkers'].cumsum()
# Plot the cumulative sum of sucessful walkers over time
plt.plot(model_data.index, model_data['cumulative_sucessful_walkers'])
plt.xlabel('Time')
plt.ylabel('Cumulative Sucessful Walkers')
plt.title('Cumulative Sucessful Walkers Over Time')
plt.grid(True)
plt.show()
# Values over 100 are to be interpreted as walkers being sucessfull several times since the total max number of ants is 100
# |%%--%%| <mgJWQ0bqG1|64kmoHYvCD>
# Connectivity measure
def check_food_source_connectivity(food_sources, paths): #food_sources = nodes.is_nest, paths=result from BFS
connected_food_sources = set()
for source in food_sources:
if source in paths:
connected_food_sources.add(source)
connectivity = len(connected_food_sources)
return connectivity
# Calculate connectivity through BFS
current_paths = bfs(self.grid, self.grid.fields["nests"], 0.000001)
# |%%--%%| <64kmoHYvCD|JEzmDy4wuX>
# |%%--%%| <JEzmDy4wuX|U9vmSFZUyD>
# |%%--%%| <U9vmSFZUyD|r0xVXEqlAh>
# |%%--%%| <r0xVXEqlAh|6K80EwwmVN>

View File

@ -15,6 +15,7 @@ from multihex import MultiHexGridScalarFields
from mesa.time import SimultaneousActivation from mesa.time import SimultaneousActivation
from mesa.datacollection import DataCollector from mesa.datacollection import DataCollector
from agent import RandomWalkerAnt from agent import RandomWalkerAnt
from collections import deque
kwargs_paper_setup1 = { kwargs_paper_setup1 = {
"width": 100, "width": 100,
@ -62,6 +63,7 @@ kwargs_paper_setup2 = {
"resistance_map_type" : None, "resistance_map_type" : None,
} }
class ActiveWalkerModel(Model): class ActiveWalkerModel(Model):
def __init__(self, width : int, height : int, def __init__(self, width : int, height : int,
N_0 : int, # number of initial roamers N_0 : int, # number of initial roamers
@ -120,8 +122,6 @@ class ActiveWalkerModel(Model):
raise NotImplemented(f"{resistance_map_type=} is not implemented.") raise NotImplemented(f"{resistance_map_type=} is not implemented.")
self._unique_id_counter = -1 self._unique_id_counter = -1
self.max_steps = max_steps self.max_steps = max_steps
@ -135,16 +135,66 @@ class ActiveWalkerModel(Model):
for _ in range(N_f): for _ in range(N_f):
self.grid.add_food(food_size) self.grid.add_food(food_size)
# Breadth-first-search algorithm for connectivity
#def bfs(graph, start_node, threshold): #graph=grid, start_node=nest, threshold=TBD?
# visited = set()
# queue = deque([(start_node, [])])
# paths = {}
# connected_food_sources = set()
# while queue:
# current_node, path = queue.popleft()
#current_node = tuple(current_node)
# visited.add(current_node)
# if current_node in graph:
# for neighbor, m.grid.fields["A"] in graph[current_node].items():
# if neighbor not in visited and m.grid.fields["A"] >= threshold:
# new_path = path + [neighbor]
# queue.append((neighbor, new_path))
# Check if the neighbor is a food source
# if neighbor in self.grid_food:
# if neighbor not in paths:
# paths[neighbor] = new_path
# connected_food_sources.add(neighbor)
# connectivity = len(connected_food_sources)
# return connectivity
# Calculate connectivity through BFS
# current_paths = bfs(self.grid, self.grid.fields["nests"], 0.000001)
def subset_agent_count(self):
subset_agents = [agent for agent in self.schedule.agents if agent.sensitivity == self.s_0 and agent.look_for_pheromone == "B"]
count = float(len(subset_agents))
return count
self.datacollector = DataCollector( self.datacollector = DataCollector(
# model_reporters={"agent_dens": lambda m: m.agent_density()}, # model_reporters={"agent_dens": lambda m: m.agent_density()},
model_reporters = {"pheromone_a": lambda m: m.grid.fields["A"], model_reporters = {"pheromone_a": lambda m: m.grid.fields["A"],
"pheromone_b": lambda m: m.grid.fields["B"], "pheromone_b": lambda m: m.grid.fields["B"],
"alive_ants": lambda m: self.schedule.get_agent_count(),
"sucessful_walkers": lambda m: subset_agent_count(self),
#"connectivity": lambda m: check_food_source_connectivity(self.grid_food,current_paths),
}, },
agent_reporters={} agent_reporters={}
) )
self.datacollector.collect(self) # keep at end of __init___ self.datacollector.collect(self) # keep at end of __init___
#def subset_agent_count(self):
# subset_agents = [agent for agent in self.schedule.agents if agent.sensitivity == self.s_0]
# count = float(len(subset_agents))
# return count
def agent_density(self): def agent_density(self):
a = np.zeros((self.grid.width, self.grid.height)) a = np.zeros((self.grid.width, self.grid.height))
for i in range(self.grid.width): for i in range(self.grid.width):
@ -180,4 +230,4 @@ This program is free software: you can redistribute it and/or modify it under th
This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License along with this program. If not, see <https://www.gnu.org/licenses/> You should have received a copy of the GNU Affero General Public License along with this program. If not, see <https://www.gnu.org/licenses/>
""" """