55import numpy as np
66
77
8+ from mesa .spaces import CellAgent , Network
9+
810@dataclass
911class NodeCoordinates :
1012 city : int
@@ -77,7 +79,7 @@ def from_tsp_file(cls, file_path: str) -> "TSPGraph":
7779 return cls (g )
7880
7981
80- class AntTSP (mesa . Agent ):
82+ class AntTSP (CellAgent ):
8183 """
8284 An agent
8385 """
@@ -93,6 +95,7 @@ def __init__(self, model, alpha: float = 1.0, beta: float = 5.0):
9395 self ._traveled_distance = 0
9496 self .tsp_solution = []
9597 self .tsp_distance = 0
98+ self .graph = self .model .grid .G
9699
97100 def calculate_pheromone_delta (self , q : float = 100 ):
98101 results = {}
@@ -102,31 +105,36 @@ def calculate_pheromone_delta(self, q: float = 100):
102105
103106 return results
104107
108+ def move_to (self , cell ) -> None :
109+ self ._cities_visited .append (cell )
110+ if self .cell :
111+ self ._traveled_distance += self .graph [self .cell .coordinate ][cell .coordinate ]["distance" ]
112+ super ().move_to (cell )
113+
114+
105115 def decide_next_city (self ):
106116 # Random
107117 # new_city = self.random.choice(list(self.model.all_cities - set(self.cities_visited)))
108118 # Choose closest city not yet visited
109- g = self .model .grid .G
110- current_city = self .pos
111- neighbors = list (g .neighbors (current_city ))
119+ neighbors = self .cell .neighborhood ()
112120 candidates = [n for n in neighbors if n not in self ._cities_visited ]
113121 if len (candidates ) == 0 :
114- return current_city
122+ return self . cell
115123
116124 # p_ij(t) = 1/Z*[(tau_ij)**alpha * (1/distance)**beta]
117125 results = []
118126 for city in candidates :
119127 val = (
120- (g [ current_city ][city ]["pheromone" ]) ** self .alpha
121- * (g [ current_city ][city ]["visibility" ]) ** self .beta
128+ (self . graph [ self . cell . coordinate ][city . coordinate ]["pheromone" ]) ** self .alpha
129+ * (self . graph [ self . cell . coordinate ][city . coordinate ]["visibility" ]) ** self .beta
122130 )
123131 results .append (val )
124132
125133 results = np .array (results )
126134 norm = results .sum ()
127135 results /= norm
128136
129- new_city = self .model . random .choices (candidates , weights = results )[0 ]
137+ new_city = self .random .choices (candidates , weights = results )[0 ]
130138
131139 return new_city
132140
@@ -135,14 +143,11 @@ def step(self):
135143 Modify this method to change what an individual agent will do during each step.
136144 Can include logic based on neighbors states.
137145 """
138- g = self . model . grid . G
139- for idx in range (self .model .num_cities - 1 ):
146+
147+ for _ in range (self .model .num_cities - 1 ):
140148 # Pick a random city that isn't in the list of cities visited
141- current_city = self .pos
142149 new_city = self .decide_next_city ()
143- self ._cities_visited .append (new_city )
144- self .model .grid .move_agent (self , new_city )
145- self ._traveled_distance += g [current_city ][new_city ]["distance" ]
150+ self .move_to (new_city )
146151
147152 self .tsp_solution = self ._cities_visited .copy ()
148153 self .tsp_distance = self ._traveled_distance
@@ -173,14 +178,15 @@ def __init__(
173178 self .num_cities = tsp_graph .num_cities
174179 self .all_cities = set (range (self .num_cities ))
175180 self .max_steps = max_steps
176- self .grid = mesa . space . NetworkGrid (tsp_graph .g )
181+ self .grid = Network (tsp_graph .g )
177182
178183 for _ in range (self .num_agents ):
179184 agent = AntTSP (model = self , alpha = ant_alpha , beta = ant_beta )
180185
181- city = tsp_graph .cities [self .random .randrange (self .num_cities )]
182- self .grid .place_agent (agent , city )
183- agent ._cities_visited .append (city )
186+ city = self .grid .all_cells .select_random_cell ()
187+ agent .move_to (city )
188+ # self.grid.place_agent(agent, city)
189+ # agent._cities_visited.append(city) # FIXME should be endogenous to agent
184190
185191 self .num_steps = 0
186192 self .best_path = None
0 commit comments