Exemple #1
0
    def choose_next_option(self, sim=HurricaneSimulator()):
        """
        next option greedy choice. Searches through all possible options to reach shelter (if people in vehicle) and
        vertices with people
        :param sim:
        :return: Best next option. This agent is optimal
        """
        self.set_state(sim.get_state())

        cost_to_people = self.find_people(
            sim)  # Find costs for all vertices with people
        cost_to_shelter = self.find_shelter(
            sim) if sim.people_in_vehicle else [
            ]  # Find costs for all shelter vertices
        """ Find best op """
        best_op = (-1, inf)
        for cost in cost_to_people:
            if cost[1] < best_op[1]:
                best_op = cost

        for cost in cost_to_shelter:
            if cost[1] < best_op[1]:
                best_op = cost

        return best_op[0]
Exemple #2
0
    def calculate_heuristic_for_agent(self, agent, sim=HurricaneSimulator()):
        people_able_to_save = 0  # number_of_people_in_towns + agent.people_in_vehicle
        cost_to_people = agent.find_people(
            sim)  # Find costs for all vertices with people
        cost_to_shelter = agent.find_sheleter(
            sim)  # Find costs for all shelter vertices

        if len(cost_to_shelter) == 0:
            """ No shelter, we are all doomed :("""
            return 0
        """ Find closest shelter """
        closest_shelter = find_closest(cost_to_shelter)[1]
        if (1 + sim.K * agent.people_in_vehicle
            ) * closest_shelter + sim.get_time() < sim.deadline:
            """ People in vehicle can be saved """
            people_able_to_save += agent.people_in_vehicle
        else:
            """ Unable to reach shelter """
            return 0
        """ 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(
                agent.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_able_to_save += sim.graph[people[2]][
                    people[2]].num_of_people
        return people_able_to_save
Exemple #3
0
 def check_if_path_ready(self, sim=HurricaneSimulator()):
     if len(self.path) == 0:
         return -1
     next_op = self.path.pop(0)['state']
     if sim.graph[sim.get_state()][next_op].weight == -1:
         return -1
     return next_op
Exemple #4
0
    def choose_next_option(self, sim=HurricaneSimulator()):
        self.set_state(sim.get_state())
        """ Check precalculated path"""

        best_state = self.build_full_state(sim)
        best_sim = copy.deepcopy(sim)
        tree = Node(state=best_state, sim=sim)
        current_tree_node = tree

        while not self.is_goal(best_state, best_sim):
            """ Explore all options"""
            self.expanded_nodes += 1
            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])
                current_tree_node.children.append(
                    Node(state=self.build_full_state(sim_emulation),
                         sim=sim_emulation,
                         g=action[1],
                         h=self.calculate_heuristic_for_action(
                             action[1], sim_emulation)))
            break
        final_action = self.find_best_branch_to_explore(tree.children)
        go_to_state = final_action.state[
            'state'] if final_action is not None else -1
        return go_to_state
Exemple #5
0
    def choose_next_option(self, sim=HurricaneSimulator()):
        self.set_state(sim.get_state())

        if self.turn_to_wait > 1:
            self.turn_to_wait -= 1
            return -1

        elif self.turn_to_wait == 1:
            lowest_cost = self.find_lowest(sim)
            if lowest_cost[1] != inf:
                # block
                sim.graph[self.state][lowest_cost[1]].weight = -1
                sim.graph[lowest_cost[1]][self.state].weight = -1
            self.turn_to_wait -= 1
            return -1

        elif self.turn_to_wait == 0:
            lowest_cost = self.find_lowest(sim)
            if lowest_cost[1] != inf:
                return lowest_cost[1]
            else:
                return -1

        elif self.turn_to_wait < 0:
            self.turn_to_wait = self.state
            return -1
Exemple #6
0
 def find_lowest(self, sim=HurricaneSimulator()):
     weight_grid = sim.get_weights()
     lowest_cost = (-1, inf)
     for i in range(sim.num_of_vertices):
         if 0 < weight_grid[self.state][i] < lowest_cost[1]:
             lowest_cost = (weight_grid[self.state][i], i)
     return lowest_cost
Exemple #7
0
 def find_sheleter(self, sim=HurricaneSimulator()):
     """
     This function finds the cost to all shelter nodes
     :param sim:  the environment
     :return: list of tuples: (next vertex, cost to final destination)
     """
     shelter_nodes = sim.get_shelter()
     return self.search_grid(shelter_nodes, sim.get_state(), sim)
Exemple #8
0
 def find_people(self, sim=HurricaneSimulator()):
     """
     This function finds the cost to all nodes with people
     :param sim:  the environment
     :return: list of tuples: (next vertex, cost to final destination)
     """
     people_nodes = sim.get_people()
     return self.search_grid(people_nodes, sim.get_state(), sim)
Exemple #9
0
    def recursive_tree(self,
                       depth,
                       is_zero_sum=True,
                       sim=HurricaneSimulator(),
                       alpha=-inf,
                       beta=inf):
        """
        Main function. Recursively find for each action what is the score and return the action with the best score
        :param depth:
        :param is_zero_sum:
        :param alpha:
        :param beta:
        :param sim:
        :return:
        """

        max_agent = True if (depth == 0 or not (depth % 2)) else False
        max_agent_id = sim.agent_index if max_agent else 1 - sim.agent_index
        ''' Check if terminal or depth reached an end '''
        if self.is_terminal(sim):
            return self.value(sim)
        if depth == self.MAX_DEPTH:
            print("exceeded depth limit")
            return self.heuristic(sim)
        ''' Set vars '''
        best_value = [-inf] * len(sim.all_agents)
        best_move = [-1, 1]
        ''' Check all possible actions '''
        for action in self.get_all_possible_actions(sim):
            if action[0] == -1:
                continue
            sim_emulator = deepcopy(sim)
            sim_emulator.apply_action(action[0])
            new_value = self.recursive_tree(depth + 1, is_zero_sum,
                                            sim_emulator, alpha, beta)
            if self.is_new_action_better(best_value, new_value, sim):
                best_value = new_value
                best_move = action

            if is_zero_sum:

                max_agent_score = self.get_max_agent_score(
                    new_value, max_agent_id)
                if max_agent:
                    "max agent"
                    if max_agent_score >= beta:
                        return new_value
                    alpha = max(alpha, max_agent_score)
                else:
                    "min agent"
                    if max_agent_score <= alpha:
                        return new_value
                    beta = min(beta, max_agent_score)
        ''' return values '''
        if depth == 0:
            return best_move
        else:
            return best_value
Exemple #10
0
 def is_new_action_better(self,
                          best_value,
                          new_value,
                          sim_emulator=HurricaneSimulator()):
     """
     check, based on game type, if the new value is better than current best value
     Note that this function is called after apply_action is performed, so the player index
     is switched. Thus, we use "sim_emulator.agent_index - 1" to refer to the right player.
     """
     raise NotImplementedError("")
Exemple #11
0
def game():
    query()
    sim = HurricaneSimulator(agents, K, config_file=config_file)
    while sim.ok():
        if DEBUG:
            sim.print_all()
            print("=================================\n\n\n\n")
        action = sim.current_agent.choose_next_option(sim)
        sim.apply_action(action)
    print("\n\n\n-------------------------\n#### Final result ####\n\n")
    sim.print_all()
Exemple #12
0
 def is_new_action_better(self,
                          best_value,
                          new_value,
                          sim_emulator=HurricaneSimulator()):
     """ A semi-cooperative game: each agent tries to maximize its own score.
     The agent disregards the other agent score, except that ties are broken cooperatively. """
     return (new_value[sim_emulator.agent_index] >
             best_value[sim_emulator.agent_index]
             or (new_value[sim_emulator.agent_index]
                 == best_value[sim_emulator.agent_index]
                 and new_value[1 - sim_emulator.agent_index] >
                 best_value[1 - sim_emulator.agent_index]))
Exemple #13
0
 def heuristic(self, sim=HurricaneSimulator()):
     """
     For cutoff purposes.
     The heuristic calculates most optimistic results for each agent.
     The heuristic for an agent assumes that there are no other agents in the game,
     and calculates how many people it is possible to save.
     """
     return [
         agent.people_saved +
         self.calculate_heuristic_for_agent(agent, sim)
         for agent in sim.all_agents
     ]
    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
        return self.path.pop(0)['state']
Exemple #15
0
 def is_terminal(sim=HurricaneSimulator()):
     """
     Checks if reached a terminal point, i.e., no more people to save, or time is up
     :param sim:
     :return:
     """
     if sim.time >= sim.deadline:
         return True
     if (sim.get_number_of_people_in_towns() +
             sum([agent.people_in_vehicle
                  for agent in sim.all_agents])) == 0:
         return True
     return False
Exemple #16
0
 def get_all_possible_actions(sim=HurricaneSimulator()):
     """
     Find all possible actions from a specific node
     :param sim: an environment
     :return: a list of tuples. Each tuple is:
     (the vertex to go to, the cost to that vertex (for A*), the heuristic of the vertex)
     """
     weights = sim.get_weights()
     actions = [(-1, 1)]  # NoOp
     for vertex, cost in enumerate(weights[sim.current_agent.get_state()]):
         if cost != -1:
             action = (vertex, cost)
             actions.append(action)
     return actions
Exemple #17
0
 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
Exemple #18
0
    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
Exemple #19
0
def game():
    query()
    for agent in agents:
        sim = HurricaneSimulator(K, config_file=config_file)
        sim.state = agent.get_state()
        while sim.ok():
            if DEBUG:
                sim.print_all()
                print("=================================\n\n\n\n")
            action = agent.choose_next_option(sim)
            sim.apply_action(action, agent.should_pick_and_drop)
        print("\n\n\n-------------------------\n#### Final result ####\n\n")
        sim.print_all()
        print("+++++ Agent expanded %d nodes +++++" % agent.expanded_nodes)
        P = sim.people_saved * f_value + agent.expanded_nodes
        print("##### Agent performance is %d #####" % P)
Exemple #20
0
    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
Exemple #21
0
 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
Exemple #22
0
 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
Exemple #23
0
 def value(sim=HurricaneSimulator()):
     """ How many people were saved by each agent """
     return [agent.people_saved for agent in sim.all_agents]
Exemple #24
0
 def choose_next_option(self, sim=HurricaneSimulator()):
     raise NotImplementedError("")
Exemple #25
0
    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)
Exemple #26
0
 def choose_next_option(self, sim=HurricaneSimulator()):
     print('You are at: ', self.get_state())
     next_state = input("Choose next step:")
     return int(next_state)
Exemple #27
0
 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]