Exemplo n.º 1
0
    def solve_by_greedy_best_first(self, head: TreeNode, target_pos: Pos):
        """
        Solve the Bloxorz problem using A* algorithm.
        :param head: head node.
        :param target_pos: target position for heuristic estimates.
        """

        # compute the heuristic cost from all valid positions to the target positions
        heuristic_costs = self.compute_heuristic_costs(target_pos)
        head.f_cost = self.min_h_cost(heuristic_costs, head)
        self.set_cost_visited(head.brick.pos, 0)

        expanded_nodes = list()

        steps = 0
        node = head

        print("Step: {}, Depth: {}, Cost: {} - {}".format(
            steps, self.get_node_depth(head),
            self.get_cost_visited(head.brick.pos), str(head)))
        self.show(head.brick)

        while True:
            for next_pos, direction in self.next_valid_move(node, []):

                # new node and estimated cost.
                new_node = TreeNode(Brick(next_pos))
                h_cost = self.min_h_cost(heuristic_costs, new_node)

                new_node.f_cost = h_cost
                # set current node's child pointer.
                setattr(node, direction.name.lower(),
                        new_node)  # node.{left|right|up|down} -> new_node

                # link new_node to the current node.
                new_node.parent = node
                new_node.dir_from_parent = direction
                heappush(expanded_nodes, new_node)
                self.debug("{:10s}: {:21s} - {} [f_cost: {:.2f}] ".format(
                    "added", "new", str(new_node), new_node.f_cost))

            node = heappop(expanded_nodes)
            self.debug("{:10s}: {:21s} - {}".format("removed", "frontier node",
                                                    str(node)))

            # update cost of this node
            self.set_cost_visited(
                node.brick.pos,
                self.get_cost_visited(node.parent.brick.pos) + 1)

            steps += 1
            print("Step: {}, Depth: {}, Cost: {} - {} [f_cost: {:.2f}]".format(
                steps, self.get_node_depth(node),
                self.get_cost_visited(node.brick.pos), str(node), node.f_cost))
            self.show(node.brick)

            # if goal state is dequeued, mark the search as completed.
            if node.brick.pos == target_pos:
                break

        print("\nGreedy Best First SEARCH COMPLETED !")
        return
Exemplo n.º 2
0
    def solve_by_astar(self, head: TreeNode, target_pos: Pos):
        """
        Solve the Bloxorz problem using A* algorithm.
        :param head: head node.
        :param target_pos: target position for heuristic estimates.
        """

        # compute the heuristic cost from all valid positions to the target positions
        heuristic_costs = self.compute_heuristic_costs(target_pos)
        head.f_cost = self.min_h_cost(heuristic_costs, head)
        self.set_cost_visited(head.brick.pos, 0)

        expanded_nodes = list()

        steps = 0
        node = head

        print("Step: {}, Depth: {}, Cost: {} - {}".format(
            steps, self.get_node_depth(head),
            self.get_cost_visited(head.brick.pos), str(head)))
        self.show(head.brick)

        while True:
            for next_pos, direction in self.next_valid_move(node, []):

                g_cost = self.get_cost_visited(node.brick.pos) + 1

                # if the node is not visited, add to expanded queue.
                # if the node is visited, but has lower actual cost than previously recorded, add to expanded queue.
                if next_pos not in self.cost_visited or g_cost < self.get_cost_visited(
                        next_pos):
                    # new node and estimated cost.
                    new_node = TreeNode(Brick(next_pos))
                    h_cost = self.min_h_cost(heuristic_costs, new_node)

                    new_node.f_cost = g_cost + h_cost
                    # set current node's child pointer.
                    setattr(node, direction.name.lower(),
                            new_node)  # node.{left|right|up|down} -> new_node

                    # link new_node to the current node.
                    new_node.parent = node
                    new_node.dir_from_parent = direction
                    heappush(expanded_nodes, new_node)
                    self.debug(
                        "{:10s}: {:21s} - {} [f_cost: {:.2f} = {} + {:.2f}] ".
                        format("added", "new | visited & cheap", str(new_node),
                               new_node.f_cost, g_cost, h_cost))
                else:
                    self.debug(
                        "{:10s}: {:21s} - [hash(Parent): {}, Parent->{}] [Cost now: {}, earlier: {}]"
                        .format("rejected", "visited & costly", hash(node),
                                direction.name.lower(), g_cost,
                                self.get_cost_visited(next_pos)))

            node = heappop(expanded_nodes)
            self.debug("{:10s}: {:21s} - {}".format("removed", "frontier node",
                                                    str(node)))

            # update cost of this node
            self.set_cost_visited(
                node.brick.pos,
                self.get_cost_visited(node.parent.brick.pos) + 1)

            steps += 1
            print("Step: {}, Depth: {}, Cost: {} - {} [f_cost: {:.2f}]".format(
                steps, self.get_node_depth(node),
                self.get_cost_visited(node.brick.pos), str(node), node.f_cost))
            self.show(node.brick)

            # if goal state is dequeued, mark the search as completed.
            if node.brick.pos == target_pos:
                break

        print("\nA* SEARCH COMPLETED !")
        print("Optimal path is as below -> \n")
        self.show_optimal_path(node)
        return