diff --git a/AgRobotSwarmForSearch/search.py b/AgRobotSwarmForSearch/search.py index 276dee913c9078d2b475e0297822cf6d692c4908..eafe6fc790fbba8655014aedd78ac9523e3796ec 100644 --- a/AgRobotSwarmForSearch/search.py +++ b/AgRobotSwarmForSearch/search.py @@ -119,6 +119,7 @@ class Simulation: return [n for n in self.sim_graph.neighbors(node)] def expand(self) -> tuple[bool, str]: + ### this has grown very badly ### Please rewrite self.current_node = self.chosen self.mark_expansion_step(self.current_node) self.expansion_step += 1 @@ -130,17 +131,9 @@ class Simulation: children = sorted(self.generate_child_nodes(self.current_node)) for child in children: # check if child already in explored or frontier + if child in self.explored_set: continue - if child in self.frontier_set: - continue - - # create entry in frontier - self.frontier.append((self.current_node, child)) - self.frontier_history["item"].append((self.current_node, child)) - self.frontier_history_unsorted["item"].append((self.current_node, child)) - self.frontier_history["avail"].append(True) - self.frontier_history_unsorted["step"].append("") # calculate the path cost g(n) and heuristic values h(n) cost_to_node = self.get_cost_of_current_path() @@ -148,28 +141,82 @@ class Simulation: (self.current_node, child) ]["dist"] path_cost = cost_to_node + cost_from_node_to_child - self.frontier_history["path_cost"].append(path_cost) - self.frontier_history_unsorted["path_cost"].append(path_cost) heuristic = self.get_heuristic(node=child) - self.frontier_history["heuristic"].append(heuristic) - self.frontier_history_unsorted["heuristic"].append(heuristic) - - # calculate f(n) - if self.search_method == "UCS": - # f(n) = g(n) - self.frontier_history["cost"].append(path_cost) - self.frontier_history_unsorted["cost"].append(path_cost) - elif self.search_method == "GreedyBestFirst": - # f(n) = h(n) - self.frontier_history["cost"].append(heuristic) - self.frontier_history_unsorted["cost"].append(heuristic) - elif self.search_method == "A*": - # f(n) = g(n) + h(n) - self.frontier_history["cost"].append(path_cost + heuristic) - self.frontier_history_unsorted["cost"].append(path_cost + heuristic) + + # check if cheaper version is available if already in frontier + if child in self.frontier_set: + # when using BFS or DFS continue without checking + if self.search_method == "DFS" or self.search_method == "BFS": + continue + hist_idx = next( + i + for i, (*_, v) in enumerate(self.frontier_history["item"]) + if v == child + ) + hist_unsorted_idx = next( + i + for i, (*_, v) in enumerate(self.frontier_history_unsorted["item"]) + if v == child + ) + + if self.search_method == "UCS": + if self.frontier_history["cost"][hist_idx] <= path_cost: + continue + if self.search_method == "GreedyBestFirst": + if self.frontier_history["cost"][hist_idx] <= heuristic: + continue + if self.search_method == "A*": + if self.frontier_history["cost"][hist_idx] <= path_cost + heuristic: + continue + + # update entry in frontier_hist + self.frontier_history["item"][hist_idx] = (self.current_node, child) + self.frontier_history_unsorted["item"][hist_unsorted_idx] = ( + self.current_node, + child, + ) + self.frontier_history["avail"][hist_idx] = True + self.frontier_history_unsorted["step"][hist_unsorted_idx] = "" + + self.frontier_history["path_cost"][hist_idx] = path_cost + self.frontier_history_unsorted["path_cost"][ + hist_unsorted_idx + ] = path_cost + self.frontier_history["heuristic"][hist_idx] = heuristic + self.frontier_history_unsorted["heuristic"][ + hist_unsorted_idx + ] = heuristic else: - self.frontier_history["cost"].append(path_cost) - self.frontier_history_unsorted["cost"].append(path_cost) + # create entry in frontier + self.frontier.append((self.current_node, child)) + self.frontier_history["item"].append((self.current_node, child)) + self.frontier_history_unsorted["item"].append( + (self.current_node, child) + ) + self.frontier_history["avail"].append(True) + self.frontier_history_unsorted["step"].append("") + + self.frontier_history["path_cost"].append(path_cost) + self.frontier_history_unsorted["path_cost"].append(path_cost) + self.frontier_history["heuristic"].append(heuristic) + self.frontier_history_unsorted["heuristic"].append(heuristic) + + # calculate f(n) + if self.search_method == "UCS": + # f(n) = g(n) + self.frontier_history["cost"].append(path_cost) + self.frontier_history_unsorted["cost"].append(path_cost) + elif self.search_method == "GreedyBestFirst": + # f(n) = h(n) + self.frontier_history["cost"].append(heuristic) + self.frontier_history_unsorted["cost"].append(heuristic) + elif self.search_method == "A*": + # f(n) = g(n) + h(n) + self.frontier_history["cost"].append(path_cost + heuristic) + self.frontier_history_unsorted["cost"].append(path_cost + heuristic) + else: + self.frontier_history["cost"].append(path_cost) + self.frontier_history_unsorted["cost"].append(path_cost) if self.search_method == "DFS" or self.search_method == "BFS": # # test every child added to frontier for goal