further plotting experiments
This commit is contained in:
		
							
								
								
									
										18
									
								
								agent.py
									
									
									
									
									
								
							
							
						
						
									
										18
									
								
								agent.py
									
									
									
									
									
								
							| @@ -9,7 +9,7 @@ License: AGPL 3 (see end of file) | ||||
|  | ||||
| """ | ||||
| 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 | ||||
| @@ -22,7 +22,7 @@ class RandomWalkerAnt(Agent): | ||||
|     def __init__(self, unique_id, model, | ||||
|                  look_for_pheromone=None, | ||||
|                  drop_pheromone=None, | ||||
|                  sensitivity_max = 30000, | ||||
|                  sensitivity_max = 10000, | ||||
|                  ) -> None: | ||||
|  | ||||
|         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] | ||||
|             # gets interpreted as slices, not multiple singular 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) | ||||
|  | ||||
|             #inv_weights = resistance/ np.sum(resistance) | ||||
|             #weights = 1 - inv_weights | ||||
|             #weights /= np.sum(weights) | ||||
|             return weights | ||||
|  | ||||
|     def _choose_next_pos(self): | ||||
| @@ -103,7 +105,7 @@ class RandomWalkerAnt(Agent): | ||||
|             """ | ||||
|             combined = res_weights * walk_weights | ||||
|             normalized = combined / np.sum(combined) | ||||
|             return list(normalized) | ||||
|             return normalized | ||||
|  | ||||
|         def _pick_from_remaining_five(remaining_five): | ||||
|             """ | ||||
| @@ -213,8 +215,6 @@ class RandomWalkerAnt(Agent): | ||||
|         self._prev_pos = self.pos | ||||
|  | ||||
|     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 | ||||
|         if self.energy < self.model.e_min: | ||||
|             self.model.schedule.remove(self) | ||||
| @@ -222,6 +222,10 @@ class RandomWalkerAnt(Agent): | ||||
|             self._choose_next_pos() | ||||
|             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): | ||||
|         if(self.drop_pheromone is not None): | ||||
|             self.pheromone_drop_rate -= self.pheromone_drop_rate * self.model.beta | ||||
|   | ||||
| @@ -2,7 +2,7 @@ | ||||
| import numpy as np | ||||
| 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 = X*2, Y*2 | ||||
|  | ||||
| @@ -28,4 +28,4 @@ def plot_hexagon(A, title=None): | ||||
|  | ||||
|     if(title is not None): | ||||
|         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=}") | ||||
|  | ||||
|  | ||||
| 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 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.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)): | ||||
|     a[np.nonzero(model.grid.fields['nests'])] = -1 | ||||
|     plot_hexagon(a, title="food locations", block=False) | ||||
|     for _ in tqdm(range(model.max_steps)): | ||||
|         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 | ||||
|   | ||||
		Reference in New Issue
	
	Block a user