Merge branch 'viviane'

This commit is contained in:
Alexander Bocken 2023-06-26 11:10:31 +02:00
commit 7c19031ca2
Signed by: Alexander
GPG Key ID: 1D237BE83F9B05E8
3 changed files with 147 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,
@ -112,8 +113,8 @@ class RandomWalkerAnt(Agent):
self.energy = self.model.e_0 self.energy = self.model.e_0
#now look for other pheromone #now look for other pheromone
self.drop_pheromone = "B"
self.look_for_pheromone = "A" self.look_for_pheromone = "A"
self.drop_pheromone = "B"
self._prev_pos = neighbor self._prev_pos = neighbor
self._next_pos = self.pos self._next_pos = self.pos
@ -127,11 +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
self.model.successful_ants += 1
# 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):

95
main.py
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
@ -186,6 +187,7 @@ def check_ants_follow_gradient():
# main() # main()
from model import kwargs_paper_setup1 as kwargs from model import kwargs_paper_setup1 as kwargs
# kwargs["N_m"] = 10000
model = ActiveWalkerModel(**kwargs) model = ActiveWalkerModel(**kwargs)
from hexplot import plot_hexagon from hexplot import plot_hexagon
@ -213,3 +215,94 @@ 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
@ -98,6 +100,7 @@ class ActiveWalkerModel(Model):
self.q_tr : float = q_tr # threshold under which ant cannot distinguish concentrations self.q_tr : float = q_tr # threshold under which ant cannot distinguish concentrations
self.e_min : float = e_min # energy at which walker dies self.e_min : float = e_min # energy at which walker dies
self.N_f : int = N_f #num food sources self.N_f : int = N_f #num food sources
self.successful_ants = 0 # for viviane's graph
fields=["A", "B", "nests", "food", "res"] fields=["A", "B", "nests", "food", "res"]
self.schedule = SimultaneousActivation(self) self.schedule = SimultaneousActivation(self)
@ -120,8 +123,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
@ -136,15 +137,60 @@ 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)
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: m.schedule.get_agent_count(),
"sucessful_walkers": lambda m: m.successful_ants,
#"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):