further plotting experiments
This commit is contained in:
parent
7b5627fafc
commit
c4ee305256
18
agent.py
18
agent.py
@ -9,7 +9,7 @@ License: AGPL 3 (see end of file)
|
|||||||
|
|
||||||
"""
|
"""
|
||||||
TO DISCUSS:
|
TO DISCUSS:
|
||||||
Is the separation of energy and sensitivity useful?
|
Is the separation of energy and sensitivity useful? -> only if we have the disconnect via resistance
|
||||||
|
|
||||||
"""
|
"""
|
||||||
import numpy as np
|
import numpy as np
|
||||||
@ -22,7 +22,7 @@ class RandomWalkerAnt(Agent):
|
|||||||
def __init__(self, unique_id, model,
|
def __init__(self, unique_id, model,
|
||||||
look_for_pheromone=None,
|
look_for_pheromone=None,
|
||||||
drop_pheromone=None,
|
drop_pheromone=None,
|
||||||
sensitivity_max = 30000,
|
sensitivity_max = 10000,
|
||||||
) -> None:
|
) -> None:
|
||||||
|
|
||||||
super().__init__(unique_id=unique_id, model=model)
|
super().__init__(unique_id=unique_id, model=model)
|
||||||
@ -81,9 +81,11 @@ class RandomWalkerAnt(Agent):
|
|||||||
# bit round-about but self.model.grid.fields['res'][positions]
|
# bit round-about but self.model.grid.fields['res'][positions]
|
||||||
# gets interpreted as slices, not multiple singular positions
|
# gets interpreted as slices, not multiple singular positions
|
||||||
resistance = np.array([ self.model.grid.fields['res'][x,y] for x,y in positions ])
|
resistance = np.array([ self.model.grid.fields['res'][x,y] for x,y in positions ])
|
||||||
easiness = np.max(self.model.grid.fields['res']) - resistance + 1e-15 # + epsilon to not divide by zero
|
easiness = np.max(self.model.grid.fields['res']) - resistance + np.min(self.model.grid.fields['res']) + 1e-15 # + epsilon to not divide by zero
|
||||||
weights = easiness/ np.sum(easiness)
|
weights = easiness/ np.sum(easiness)
|
||||||
|
#inv_weights = resistance/ np.sum(resistance)
|
||||||
|
#weights = 1 - inv_weights
|
||||||
|
#weights /= np.sum(weights)
|
||||||
return weights
|
return weights
|
||||||
|
|
||||||
def _choose_next_pos(self):
|
def _choose_next_pos(self):
|
||||||
@ -103,7 +105,7 @@ class RandomWalkerAnt(Agent):
|
|||||||
"""
|
"""
|
||||||
combined = res_weights * walk_weights
|
combined = res_weights * walk_weights
|
||||||
normalized = combined / np.sum(combined)
|
normalized = combined / np.sum(combined)
|
||||||
return list(normalized)
|
return normalized
|
||||||
|
|
||||||
def _pick_from_remaining_five(remaining_five):
|
def _pick_from_remaining_five(remaining_five):
|
||||||
"""
|
"""
|
||||||
@ -213,8 +215,6 @@ class RandomWalkerAnt(Agent):
|
|||||||
self._prev_pos = self.pos
|
self._prev_pos = self.pos
|
||||||
|
|
||||||
def step(self):
|
def step(self):
|
||||||
self.sensitivity -= self.model.d_s
|
|
||||||
self.energy -= self.model.grid.fields['res'][self.pos] * self.model.d_e
|
|
||||||
# Die and get removed if no energy
|
# Die and get removed if no energy
|
||||||
if self.energy < self.model.e_min:
|
if self.energy < self.model.e_min:
|
||||||
self.model.schedule.remove(self)
|
self.model.schedule.remove(self)
|
||||||
@ -222,6 +222,10 @@ class RandomWalkerAnt(Agent):
|
|||||||
self._choose_next_pos()
|
self._choose_next_pos()
|
||||||
self._adjust_pheromone_drop_rate()
|
self._adjust_pheromone_drop_rate()
|
||||||
|
|
||||||
|
self.sensitivity -= self.model.d_s
|
||||||
|
self.energy -= self.model.grid.fields['res'][self.pos] * self.model.d_e
|
||||||
|
|
||||||
|
|
||||||
def _adjust_pheromone_drop_rate(self):
|
def _adjust_pheromone_drop_rate(self):
|
||||||
if(self.drop_pheromone is not None):
|
if(self.drop_pheromone is not None):
|
||||||
self.pheromone_drop_rate -= self.pheromone_drop_rate * self.model.beta
|
self.pheromone_drop_rate -= self.pheromone_drop_rate * self.model.beta
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
import numpy as np
|
import numpy as np
|
||||||
import matplotlib.pyplot as plt
|
import matplotlib.pyplot as plt
|
||||||
|
|
||||||
def plot_hexagon(A, title=None):
|
def plot_hexagon(A, title=None, block=True):
|
||||||
X, Y = np.meshgrid(range(A.shape[0]), range(A.shape[-1]))
|
X, Y = np.meshgrid(range(A.shape[0]), range(A.shape[-1]))
|
||||||
X, Y = X*2, Y*2
|
X, Y = X*2, Y*2
|
||||||
|
|
||||||
@ -28,4 +28,4 @@ def plot_hexagon(A, title=None):
|
|||||||
|
|
||||||
if(title is not None):
|
if(title is not None):
|
||||||
plt.title(title)
|
plt.title(title)
|
||||||
plt.show(block=False)
|
plt.show(block=block)
|
||||||
|
145
main.py
145
main.py
@ -226,24 +226,145 @@ def viviane_bfs_example_run():
|
|||||||
print(f"{xv=}")
|
print(f"{xv=}")
|
||||||
|
|
||||||
|
|
||||||
from model import kwargs_paper_setup1 as kwargs
|
|
||||||
if __name__ == "__main__":
|
|
||||||
print("Test")
|
|
||||||
kwargs["resistance_map_type"] = "perlin"
|
|
||||||
print(kwargs)
|
|
||||||
model = ActiveWalkerModel(**kwargs)
|
|
||||||
|
|
||||||
|
def fixed_distance_tests():
|
||||||
|
"""
|
||||||
|
position a target food source a known distance away from nest
|
||||||
|
check for no. successful ants for n runs
|
||||||
|
"""
|
||||||
|
|
||||||
|
from tqdm import tqdm
|
||||||
|
runs = 10
|
||||||
|
from model import kwargs_paper_setup1 as kwargs
|
||||||
|
kwargs["N_f"] = 0
|
||||||
|
kwargs["gamma"] /= 2 # field decays three times slower
|
||||||
|
kwargs["beta"] /= 2 # drop rates decays three times slower
|
||||||
|
kwargs["d_s"] /= 2 # drop rates decays three times slower
|
||||||
|
kwargs["d_e"] /= 2 # drop rates decays three times slower
|
||||||
|
successful_walkers = {}
|
||||||
|
for distance in tqdm(range(5,30), position=0, desc="dis"):
|
||||||
|
successful_walkers[distance] = []
|
||||||
|
for _ in tqdm(range(runs), position=1, desc="run", leave=False):
|
||||||
|
model = ActiveWalkerModel(**kwargs)
|
||||||
|
nest_location = kwargs["nest_position"]
|
||||||
|
food_location = (nest_location[0] - distance, nest_location[1])
|
||||||
|
model.grid.add_food(size=100, pos=food_location)
|
||||||
|
for _ in tqdm(range(model.max_steps), position=2, desc="step", leave=False):
|
||||||
|
model.step()
|
||||||
|
successful_walkers[distance].append(model.datacollector.get_model_vars_dataframe().reset_index()["successful_walkers"][kwargs["max_steps"]])
|
||||||
|
return successful_walkers
|
||||||
|
|
||||||
|
def fixed_distance_object_between():
|
||||||
|
"""
|
||||||
|
diameter of object: floor(50% of distance)
|
||||||
|
"""
|
||||||
|
|
||||||
|
from tqdm import tqdm
|
||||||
|
runs = 10
|
||||||
|
from model import kwargs_paper_setup1 as kwargs
|
||||||
|
kwargs["N_f"] = 0
|
||||||
|
kwargs["gamma"] /= 2 # field decays slower
|
||||||
|
kwargs["beta"] /= 2 # drop rates decays slower
|
||||||
|
kwargs["d_e"] /= 2 # live longer, search longer
|
||||||
|
kwargs["d_s"] /= 2 # live longer, search longer
|
||||||
|
successful_walkers = {}
|
||||||
|
for distance in tqdm(range(5,30), position=0, desc="dis"):
|
||||||
|
successful_walkers[distance] = []
|
||||||
|
for _ in tqdm(range(runs), position=1, desc="run", leave=False):
|
||||||
|
model = ActiveWalkerModel(**kwargs)
|
||||||
|
nest_location = kwargs["nest_position"]
|
||||||
|
food_location = (nest_location[0] - distance, nest_location[1])
|
||||||
|
object_location = (nest_location[0] - distance//2, nest_location[1])
|
||||||
|
place_blocking_object(object_location, radius=distance//4, model=model)
|
||||||
|
model.grid.add_food(size=100, pos=food_location)
|
||||||
|
for _ in tqdm(range(model.max_steps), position=2, desc="step", leave=False):
|
||||||
|
model.step()
|
||||||
|
successful_walkers[distance].append(model.datacollector.get_model_vars_dataframe().reset_index()["successful_walkers"][kwargs["max_steps"]])
|
||||||
|
return successful_walkers
|
||||||
|
|
||||||
|
def place_blocking_object(center, radius, model):
|
||||||
|
positions = [center]
|
||||||
|
next_outside = [center]
|
||||||
|
# We grow from the center and add all neighbours of the outer edge of our blocking object
|
||||||
|
# Add all neighbours of next_outside that aren't in positions to the object
|
||||||
|
# by doing this radius times we should get an object of diameter 2 * radius + 1
|
||||||
|
# positions: accumulator for all positions inside the object of radius radius
|
||||||
|
# next_outside: keep track what we added in the last go-around. These will be used in the next step.
|
||||||
|
for _ in range(radius):
|
||||||
|
outside = next_outside
|
||||||
|
next_oustide = []
|
||||||
|
|
||||||
|
#otherwise interprets the tuple as something stupid
|
||||||
|
for i in range(len(outside)):
|
||||||
|
cell = outside[i]
|
||||||
|
neighbours = model.grid.get_neighborhood(cell)
|
||||||
|
for n in neighbours:
|
||||||
|
if n not in positions:
|
||||||
|
positions.append(n)
|
||||||
|
next_outside.append(n)
|
||||||
|
|
||||||
|
# some large number in comparison to the rest of the resistance field
|
||||||
|
# such that the probability of stepping on these grid spots tend towards zero
|
||||||
|
infinity = 1e20
|
||||||
|
for pos in positions:
|
||||||
|
model.grid.fields['res'][pos] = infinity
|
||||||
|
|
||||||
|
|
||||||
|
def plot_heatmap():
|
||||||
from hexplot import plot_hexagon
|
from hexplot import plot_hexagon
|
||||||
|
from tqdm import tqdm
|
||||||
|
# nests rather far away but also partially clumped.
|
||||||
|
np.random.seed(6)
|
||||||
|
|
||||||
|
from model import kwargs_paper_setup1 as kwargs
|
||||||
|
kwargs["gamma"] /= 3 # field decays slower
|
||||||
|
kwargs["beta"] /= 3 # drop rates decays slower
|
||||||
|
kwargs["d_e"] /= 3 # live longer, search longer
|
||||||
|
kwargs["d_s"] /= 3 # live longer, search longer
|
||||||
|
|
||||||
|
model = ActiveWalkerModel(**kwargs)
|
||||||
a = np.zeros_like(model.grid.fields['food'])
|
a = np.zeros_like(model.grid.fields['food'])
|
||||||
a[np.nonzero(model.grid.fields['food'])] = 1
|
a[np.nonzero(model.grid.fields['food'])] = 1
|
||||||
plot_hexagon(a, title="Nest locations")
|
a[np.nonzero(model.grid.fields['nests'])] = -1
|
||||||
plot_hexagon(model.grid.fields['res'], title="Resistance Map")
|
plot_hexagon(a, title="food locations", block=False)
|
||||||
|
for _ in tqdm(range(model.max_steps)):
|
||||||
|
|
||||||
from tqdm import tqdm as progress_bar
|
|
||||||
for _ in progress_bar(range(model.max_steps)):
|
|
||||||
model.step()
|
model.step()
|
||||||
|
|
||||||
|
for time in np.arange(0, model.max_steps + 1, 1000):
|
||||||
|
pheromone_concentration = model.datacollector.get_model_vars_dataframe()["pheromone_a"][time]
|
||||||
|
a = pheromone_concentration
|
||||||
|
#plot_hexagon(a)
|
||||||
|
pheromone_concentration = model.datacollector.get_model_vars_dataframe()["pheromone_b"][time]
|
||||||
|
b = pheromone_concentration
|
||||||
|
#plot_hexagon(b)
|
||||||
|
c = np.max([a,b], axis=0)
|
||||||
|
c = a + b
|
||||||
|
c = np.clip(c, 0, 200)
|
||||||
|
plot_hexagon(c)
|
||||||
|
|
||||||
|
|
||||||
|
#if __name__ == "__main__":
|
||||||
|
plot_heatmap()
|
||||||
|
#print("DISTANCE TEST VS SUCCESSFUL ANTS OBJECT INBETWEEN")
|
||||||
|
#res = fixed_distance_tests()
|
||||||
|
#res = fixed_distance_object_between()
|
||||||
|
# print("Test")
|
||||||
|
#from model import kwargs_paper_setup1 as kwargs
|
||||||
|
#kwargs["resistance_map_type"] = "perlin"
|
||||||
|
# print(kwargs)
|
||||||
|
#model = ActiveWalkerModel(**kwargs)
|
||||||
|
#model.step()
|
||||||
|
|
||||||
|
# a = np.zeros_like(model.grid.fields['food'])
|
||||||
|
# a[np.nonzero(model.grid.fields['food'])] = 1
|
||||||
|
# plot_hexagon(a, title="Nest locations")
|
||||||
|
# plot_hexagon(model.grid.fields['res'], title="Resistance Map")
|
||||||
|
|
||||||
|
|
||||||
|
# from tqdm import tqdm as progress_bar
|
||||||
|
# for _ in progress_bar(range(model.max_steps)):
|
||||||
|
# model.step()
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
# Access the DataCollector
|
# Access the DataCollector
|
||||||
|
Loading…
Reference in New Issue
Block a user