def choose_next_option(self, sim=HurricaneSimulator()): self.set_state(sim.get_state()) precalculated_answer = self.check_if_path_ready(sim) if precalculated_answer != -1: return precalculated_answer best_state = self.build_full_state(sim) best_sim = copy.deepcopy(sim) tree = Node(state=best_state, sim=sim) best_child = tree best_path = list() nodes_not_expanded = [tree] current_tree_node = tree expands_in_this_search = 0 while not self.is_goal(best_state, best_sim) and self.max_expands > expands_in_this_search: """ Expand the current node """ nodes_not_expanded.remove(current_tree_node) """ Explore all options""" actions = self.get_all_possible_actions(best_sim) for action in actions: sim_emulation = copy.deepcopy(best_sim) # Not actually required for greedy search, but for A* sim_emulation.apply_action(action[0]) nodes_not_expanded.append(Node(state=self.build_full_state(sim_emulation), sim=sim_emulation, g=current_tree_node.g_score + action[1], h=self.calculate_heuristic_for_action(action[1], sim_emulation), p=current_tree_node)) """ Find best child """ best_child = self.find_best_branch_to_explore(nodes_not_expanded) best_state = best_child.state best_sim = best_child.sim current_tree_node = best_child self.expanded_nodes += 1 expands_in_this_search += 1 """ No possible way to expand """ if best_child == tree: return -1 current_tree_node = best_child while current_tree_node != tree: best_path.insert(0, current_tree_node.state) current_tree_node = current_tree_node.parent self.path = best_path ans = self.path.pop(0)['state'] return ans
def is_goal(full_state, sim=HurricaneSimulator()): """ Is a goal reached? A goal is run out the clock or best goal is saved all people :param full_state: as built by buil_full_state() method :param sim: :return: true if goal or false """ if full_state['number_of_people_to_save'] == 0: """ Reached optimal goal""" return True if full_state['time_passed'] >= sim.deadline: """ Run out of time :( """ return True return False
def is_new_action_better(best_value, new_value, sim_emulator=HurricaneSimulator()): """ Adversarial (zero sum game): each agent aims to maximize its own score minus the opposing agent's score """ cur_best = best_value[sim_emulator.agent_index] - best_value[ 1 - sim_emulator.agent_index] if isinf(best_value[1 - sim_emulator.agent_index] ) and best_value[1 - sim_emulator.agent_index] < 0: '" If the second score is - infinity, set the subtraction to be - infinity "' cur_best = -inf return new_value[sim_emulator.agent_index] - new_value[ 1 - sim_emulator.agent_index] > cur_best
def calculate_heuristic_for_action(self, cost, sim=HurricaneSimulator()): """ This function calculates the heuristic for a single. :param vertex: the vertex to which you wish to calculate the heuristic :param sim: the environment :return: a heuristic value """ number_of_people_in_towns = sim.get_number_of_people_in_towns() people_unable_to_save = number_of_people_in_towns + self.people_in_vehicle cost_to_people = self.find_people( sim) # Find costs for all vertices with people cost_to_shelter = self.find_sheleter( sim) # Find costs for all shelter vertices if len(cost_to_shelter) == 0: """ No shelter, we are all doomed :(""" return cost + people_unable_to_save * PEOPLE_UNSAVED_VALUE """ Find closest shelter """ closest_shelter = find_closest(cost_to_shelter)[1] if (1 + sim.K * self.people_in_vehicle ) * closest_shelter + sim.get_time() < sim.deadline: """ People in vehicle can be saved """ people_unable_to_save -= self.people_in_vehicle else: """ Unable to reach shelter """ return cost + people_unable_to_save * PEOPLE_UNSAVED_VALUE """ Find people in towns """ shelter_nodes = sim.get_shelter() time_elapsed = sim.get_time() for people in cost_to_people: path_to_shelter_for_person = find_closest( self.search_grid(shelter_nodes, people[2], sim)) time_elapsed_for_person = time_elapsed + people[1] + \ (1 + sim.K * sim.graph[people[2]][people[2]].num_of_people) \ * path_to_shelter_for_person[1] if time_elapsed_for_person < sim.deadline: people_unable_to_save -= sim.graph[people[2]][ people[2]].num_of_people return cost + people_unable_to_save * PEOPLE_UNSAVED_VALUE
def search_grid(self, grid, starting_index, sim=HurricaneSimulator()): """ This function performs the actual search in a grid, and calculates the cost to each vertex of interest :param grid: people or shelter grid :param sim: the environment :return: list of tuples: (next vertex, cost to final destination, final destination) """ l_cost = [] weight_grid = sim.get_weights() for i in range(sim.num_of_vertices): if grid[i][i]: path, depth_searched = dijkstra_shortest_path( weight_grid, starting_index, i) # self.steps_explored += depth_searched if len(path) == 1: """ Already at a shelter town """ l_cost.append((path[0][0], 0, path[0][0])) elif path[-1][1] != -1: l_cost.append( (path[1][0], path[-1][1], path[-1][0]) ) # set the cost for the entire path and the next step return l_cost
def build_full_state(sim=HurricaneSimulator()): """ Build a full state to work with :param sim: the env :return: a dict with (state, time, list_of_vertices_with_people, number_of_people_to_save, number_of_people_in_vehicle) """ """ Create a list of people vertices """ list_of_vertices_with_people = [] people = sim.get_people() sum_of_people = 0 for i in range(sim.num_of_vertices): sum_of_people += people[i][i] if people[i][i]: data = (i, people[i][i]) list_of_vertices_with_people.append(data) """ Create the full state """ full_state = { 'state': sim.get_state(), 'time_passed': sim.get_time(), 'list_of_vertices_with_people': list_of_vertices_with_people, 'number_of_people_to_save': sum_of_people + sim.people_in_vehicle, 'number_of_people_in_vehicle': sim.people_in_vehicle } return full_state
def choose_next_option(self, sim=HurricaneSimulator()): print('You are at: ', self.get_state()) next_state = input("Choose next step:") return int(next_state)
def is_new_action_better(self, best_value, new_value, sim_emulator=HurricaneSimulator()): """ A fully cooperative both agents aim to maximize the sum of scores. """ return sum(new_value) > sum(best_value)
def choose_next_option(self, sim=HurricaneSimulator()): raise NotImplementedError("")
def value(sim=HurricaneSimulator()): """ How many people were saved by each agent """ return [agent.people_saved for agent in sim.all_agents]
def choose_next_option(self, sim=HurricaneSimulator()): if self.is_terminal(sim): return -1 best = self.recursive_tree(0, self.is_zero_sum, sim) return best[0]