コード例 #1
0
    def choose_next_node(self):
        """
        Calculate f(x) for each new generated node from open_list.
        Choose next node.
        :return: next node.
        """

        for node in self.open_list:
            heuristic = Heuristic(current_node=node, final_node=self.final_node,
                                  heuristic=self.heuristic)
            h_score = heuristic.calculate()
            node.h = h_score
            node.f = self.get_f_score(h_score, node)

        # sort list of node by f-score, from higher to lower.
        self.open_list.sort(key=lambda x: x.f)

        if len(self.open_list) > 1 and self.open_list[0].f == self.open_list[1].f:
            return [node for node in self.open_list if node.f == self.open_list[0].f]
        else:
            self.solution_history.append(deepcopy(self.open_list[0]))
            return self.open_list[0]
コード例 #2
0
    def play_AStar(self):
        start = time()

        rootNode = deepcopy(self.board)
        generatedNodes, repeatedNodes = 1, 0

        if not rootNode.get_stor_coordinates():
            end = time()
            return 'THERE ARE NO STORAGE LOCATIONS!', (end - start)
        if not rootNode.get_box_coordinates():
            end = time()
            return 'THERE ARE NO BOX LOCATIONS!', (end - start)
        if not rootNode.get_player_loc():
            end = time()
            return 'SOKOBAN PLAYER MISSING!', (end - start)
        if rootNode.is_goal_state():
            end = time()
            return 'BOARD IS ALREADY IN GOAL STATE!', (end - start)

        H = Heuristic()
        # H.set_heuristic("manhattan2")
        heuristicVal = H.calculate(rootNode.get_stor_coordinates(),
                                   rootNode.get_box_coordinates())

        frontier1 = PriorityQueue()
        frontier2 = PriorityQueue()
        path = PriorityQueue()

        frontier1.push(rootNode, heuristicVal)
        frontier2.push(
            (rootNode.get_player_loc(), rootNode.get_box_coordinates()),
            heuristicVal)
        path.push([''], heuristicVal)
        visited = []

        deadlockConditions = 0

        # Hamza: This i represents the number of states visited, I think generated Nodes does not apply because
        # we don't explore possible moves for all of the generated nodes so the branching factor cannot use this value
        # i, b = 0, 0 # don't really need i since we can just do len(visited) for this
        b = 0
        self.branchingFactor = 0
        self.treeDepth = 0

        while True:
            # print('Generated Nodes: {}, Repeated Nodes: {}, Frontier Length: {}, Deadlock Conditions: {}'.format(
            # generatedNodes, repeatedNodes, len(frontier1.Heap), deadlockConditions))
            if not frontier1.Heap:
                end = time()
                return 'SOLUTION NOT FOUND', (end - start)

            currentNode = frontier1.pop()
            (currentPlayer, currentBoxCoordinates) = frontier2.pop()
            currentActionSequence = path.pop()

            possibleMoves = currentNode.possible_moves()
            visited.append((currentPlayer, currentBoxCoordinates))

            # Tree depth and branch factor variables
            b += len(possibleMoves)  # branching factor of the current node
            # i = len(visited) # number of visited nodes
            self.treeDepth += 1

            for move in possibleMoves:
                childNode = deepcopy(currentNode)
                generatedNodes += 1
                childNode.update_board(move)
                if (childNode.get_player_loc(),
                        childNode.get_box_coordinates()) not in visited:
                    if childNode.is_goal_state():
                        childNode.make_board_grid()
                        # childNode.display_board()
                        end = time()
                        self.branchingFactor = ceil(
                            b / len(visited))  # average branching factor
                        return str(
                            len(currentActionSequence[1:] + [move])
                        ) + ' ' + ' '.join(
                            map(lambda x: x.upper(),
                                currentActionSequence[1:] + [move])).replace(
                                    ',',
                                    '')  #, str((end - start)) + ' seconds'
                        # return None
                    if self.is_deadlock(childNode):
                        # print('DEADLOCK CONDITION')
                        deadlockConditions += 1
                        continue

                    heuristicVal = H.calculate(
                        childNode.get_stor_coordinates(),
                        childNode.get_box_coordinates())
                    cost = self.compute_cost(currentActionSequence + [move])
                    # childNode.make_board_grid()
                    # childNode.display_board()
                    frontier1.push(childNode, heuristicVal + cost)
                    frontier2.push((childNode.get_player_loc(),
                                    childNode.get_box_coordinates()),
                                   heuristicVal + cost)
                    path.push(currentActionSequence + [move],
                              heuristicVal + cost)
                else:
                    repeatedNodes += 1