Beispiel #1
0
    def search(self, problem, frontier):
        """
        Search for a solution saving new expanded nodes to a queue.

        :param problem: problem to solve
        :param frontier (Datastructures.Queue): that implements certain discipline
        :return: If solution was found return a list of actions to reach goal state from an initial state. If
        initial state is a goal state this method returns a list with a NoOpAction. If failed to find a solution
        it returns an empty list.
        """
        self._frontier = frontier
        self.clear_instrumentation()

        root = Node(problem.get_initial_state())
        # check root node before adding to a queue
        if self._check_goal_before_adding_to_frontier:
            if utils.is_goal_state(problem, root):
                self._set_path_cost(root.get_path_cost())
                return utils.actions_from_nodes(root.get_path_from_root())

        self._add_to_frontier(root)
        self._set_new_queue_size()
        # while frontier isn't empty there are still states to check
        while not self._frontier.is_empty():
            node_to_expand = self._pop_node_from_frontier()
            self._set_new_queue_size()

            # if state shouldn't be checked before adding it's time to check it now
            if not self._check_goal_before_adding_to_frontier:
                if utils.is_goal_state(problem, node_to_expand):
                    self._set_path_cost(node_to_expand.get_path_cost())
                    return utils.actions_from_nodes(
                        node_to_expand.get_path_from_root())

            # Get new nodes, check them and add to a frontier
            for fn in self.get_resulting_nodes_to_add_to_frontier(
                    node_to_expand, problem):
                if self._check_goal_before_adding_to_frontier:
                    if utils.is_goal_state(problem, fn):
                        self._set_path_cost(fn.get_path_cost())
                        return utils.actions_from_nodes(
                            fn.get_path_from_root())

                self._add_to_frontier(fn)

            self._set_new_queue_size()

        # if we are here, all frontier is empty and a goal state wasn't found. Search failed
        return self._failure()
Beispiel #2
0
    def _recursive_dls(self, curNode, problem, limit):

        # if problem.GOAL-TEST(node.STATE) then return SOLUTION(node)
        if utils.is_goal_state(problem, curNode):
            self.set_path_cost(curNode.get_path_cost())
            return utils.actions_from_nodes(curNode.get_path_from_root())
        elif limit == 0:
            # else if limit = 0 then return cutoff
            return self._cutoff()
        else:
            # else
			# cutoff_occurred? <- false
            childNodes = self.expand_node(curNode, problem)

            cutoff_occurred = False
            # for each action in problem.ACTIONS(node.STATE) do
            for node in childNodes:
                # child <- CHILD-NODE(problem, node, action)
				# result <- RECURSIVE-DLS(child, problem, limit - 1)
                result = self._recursive_dls(node, problem, limit - 1)

                # if result = cutoff then cutoff_occurred? <- true
                if self.is_cutoff(result):
                    cutoff_occurred = True
                elif not self.is_failure(result):
                    # else if result != failure then return result
                    return result

            # if cutoff_occurred? then return cutoff else return failure
            if cutoff_occurred:
                return self._cutoff()
            else:
                return self._failure()
Beispiel #3
0
    def search(self, problem, frontier):
        """
        Search for a solution saving new expanded nodes to a queue.

        :param problem: problem to solve
        :param frontier (Datastructures.Queue): that implements certain discipline
        :return: If solution was found return a list of actions to reach goal state from an initial state. If
        initial state is a goal state this method returns a list with a NoOpAction. If failed to find a solution
        it returns an empty list.
        """
        self._frontier = frontier
        self.clear_instrumentation()

        root = Node(problem.get_initial_state())
        # check root node before adding to a queue
        if self._check_goal_before_adding_to_frontier:
            if utils.is_goal_state(problem, root):
                self._set_path_cost(root.get_path_cost())
                return utils.actions_from_nodes(root.get_path_from_root())

        self._add_to_frontier(root)
        self._set_new_queue_size()
        # while frontier isn't empty there are still states to check
        while not self._frontier.is_empty():
            node_to_expand  = self._pop_node_from_frontier()
            self._set_new_queue_size()

            # if state shouldn't be checked before adding it's time to check it now
            if not self._check_goal_before_adding_to_frontier:
                if utils.is_goal_state(problem, node_to_expand):
                    self._set_path_cost(node_to_expand.get_path_cost())
                    return utils.actions_from_nodes(node_to_expand.get_path_from_root())

            # Get new nodes, check them and add to a frontier
            for fn in self.get_resulting_nodes_to_add_to_frontier(node_to_expand, problem):
                if self._check_goal_before_adding_to_frontier:
                    if utils.is_goal_state(problem, fn):
                        self._set_path_cost(fn.get_path_cost())
                        return utils.actions_from_nodes(fn.get_path_from_root())

                self._add_to_frontier(fn)

            self._set_new_queue_size()

        # if we are here, all frontier is empty and a goal state wasn't found. Search failed
        return self._failure()
Beispiel #4
0
    def _rbfs(self, problem, node, node_f, f_limit, recursive_depth):
        self._set_max_recursive_depth(recursive_depth)

        # if problem.GOAL-TEST(node.STATE) then return SOLUTION(node)
        if utils.is_goal_state(problem, node):
            return SearchResult(node, f_limit)

        # successors <- []
# for each action in problem.ACTION(node.STATE) do
# add CHILD-NODE(problem, node, action) into successors
        successors = self.expand_node(node, problem)

        # if successors is empty then return failure, infinity
        if len(successors) == 0:
            return SearchResult(None, PlusInfinity())

        # for each s in successors do
# update f with value from previous search, if any
        f = [
            max(self._evaluation_function.f(node), node_f)
            for node in successors
        ]

        # repeat
        while True:
            # best <- the lowest f-value node in successors
            best_index = self._get_best_f_value_index(f)
            # if best.f > f_limit then return failure, best.f
            if f[best_index] > f_limit:
                return SearchResult(None, f[best_index])

            # if best.f > f_limit then return failure, best.f
            alt_index = self._get_next_best_f_value_index(f, best_index)
            # result, best.f <- RBFS(problem, best, min(f_limit, alternative))
            sr = self._rbfs(problem, successors[best_index], f[best_index],
                            min(f_limit, f[alt_index]), recursive_depth + 1)
            f[best_index] = sr.get_f_cost_limit()

            # if result != failure then return result
            if sr.found_solution():
                return sr
Beispiel #5
0
    def _rbfs(self, problem, node, node_f, f_limit, recursive_depth):
        self._set_max_recursive_depth(recursive_depth)

        # if problem.GOAL-TEST(node.STATE) then return SOLUTION(node)
        if utils.is_goal_state(problem, node):
            return SearchResult(node, f_limit)

        # successors <- []
		# for each action in problem.ACTION(node.STATE) do
		# add CHILD-NODE(problem, node, action) into successors
        successors = self.expand_node(node ,problem)

        # if successors is empty then return failure, infinity
        if len(successors) == 0:
            return SearchResult(None, PlusInfinity())

        # for each s in successors do
		# update f with value from previous search, if any
        f = [max(self._evaluation_function.f(node), node_f) for node in successors]

        # repeat
        while True:
            # best <- the lowest f-value node in successors
            best_index = self._get_best_f_value_index(f)
            # if best.f > f_limit then return failure, best.f
            if f[best_index] > f_limit:
                return SearchResult(None, f[best_index])

            # if best.f > f_limit then return failure, best.f
            alt_index = self._get_next_best_f_value_index(f, best_index)
            # result, best.f <- RBFS(problem, best, min(f_limit, alternative))
            sr = self._rbfs(problem, successors[best_index], f[best_index], min(f_limit, f[alt_index]), recursive_depth + 1)
            f[best_index] = sr.get_f_cost_limit()

            # if result != failure then return result
            if sr.found_solution():
                return sr