Пример #1
0
def solve(problem: SearchProblem, heuristic: Callable) -> List[str]:
    """See 2_implementation_notes.md for more details.

    Your search algorithms needs to return a list of actions that reaches the
    goal from the start state in the given problem. The elements of this list
    need to be one or more references to the attributes NORTH, SOUTH, EAST and
    WEST of the class Directions.
    """
    # set:store the node already explored
    explored = set()
    # set:store the node wait for evaluate
    frontiers=PriorityQueue()
    #initial node
    s0 = problem.get_initial_state()
    a=SearchNode(s0)
    #initialize the dictionary to store f_cost with key "node"
    f_cost={}
    f_cost[s0]=heuristic(s0,problem)
    # import priorityqueque to record frontiers and ordered by f_cost, A* search always find the smallest f_cost in the frontiers
    frontiers.push(a,f_cost[s0])
    while not frontiers.is_empty():
        cur_key= frontiers.pop()
        #if goal then return the actions
        if problem.goal_test(cur_key.state):
            return route(cur_key)
        explored.add(cur_key.state)
        for successor,action, cost in problem.get_successors(cur_key.state):
            b=SearchNode(successor,action,cur_key.path_cost+cost,cur_key)
            #if in the explored, it means return back, so ignore it
            if successor in explored:
                continue
            f_cost[successor]=b.path_cost+heuristic(successor,problem)
            frontiers.push(b,f_cost[successor])
Пример #2
0
def solve(problem: SearchProblem) -> List[str]:
    """See 2_implementation_notes.md for more details.
        
        Your search algorithms needs to return a list of actions that reaches the
        goal from the start state in the given problem. The elements of this list
        need to be one or more references to the attributes NORTH, SOUTH, EAST and
        WEST of the class Directions.
        
        (problem: SearchProblem) -> List[str]
        """
    #get the initial postion and set frontiers
    s0 = problem.get_initial_state()
    frontiers = Queue()
    explored = set()
    #initiate the frontier by the start point
    a = SearchNode(s0)
    frontiers.push(a)
    #expand the frontiers
    while not frontiers.is_empty():
        #our goal is to
        cur = frontiers.pop()
        if problem.goal_test(cur.state):
            route = []
            while cur.parent != None:
                route.append(cur.action)
                cur = cur.parent
            return route[::-1]
        else:
            explored.add(cur.state)
            for successor, action, cost in problem.get_successors(cur.state):
                b = SearchNode(successor, action, cur.path_cost + cost, cur)
                if successor not in explored:
                    frontiers.push(b)
Пример #3
0
def recursive_dls(node, problem, depth_limit, explored, path):
    explored.append(node.state)  # Add the state to explored.
    cut_off = False

    if problem.goal_test(node.state):
        return 'success'
    elif node.depth == depth_limit:
        cut_off = True
    else:
        for successor, action, cost in problem.get_successors(node.state):
            if successor in explored:
                continue

            result = recursive_dls(
                SearchNode(state=successor,
                           action=action,
                           path_cost=node.path_cost + cost,
                           depth=node.depth + 1), problem, depth_limit,
                explored, path)

            if result == 'cutoff':
                cut_off = True
            elif result == 'success':
                path.append(action)
                return 'success'

    # Remove this state from explored, to preserve the O(bm) memory requirement.
    explored.pop()

    if cut_off:
        return 'cutoff'
    else:
        return 'failure'
Пример #4
0
def dls(problem, depth):
    # Initial the variables
    path = list()
    touched = set()
    root = SearchNode(problem.get_initial_state(), None, 0, None, depth)
    # Put the variables into recursive function
    return recursive_dfs(root, problem, path, depth, touched)
Пример #5
0
def solve(problem):
    """ *** YOUR CODE HERE *** """
    # util.raise_not_defined() #Remove this line when you have implemented BrFS

    stack = Stack()
    depth_limit = 0
    s0 = problem.get_initial_state()
    sn_root = SearchNode(s0)

    # depth += 1
    check = None
    while True:
        explored = []
        explored.append(s0)
        stack = Stack()

        stack.push(sn_root)
        while not stack.is_empty():
            # print("here")
            # check_limit = stack.peek()
            frontier = stack.pop()
            # if depth_limit != 0:
            #     print(str(frontier.action) + " "+ str(frontier.depth))
            check = check_goal(frontier, problem)

            if check != None:
                return check
            else:
                if (frontier.depth == depth_limit):
                    continue
                for successor, action, cost in problem.get_successors(
                        frontier.state):
                    # if successor != frontier.state:
                    if successor not in explored:
                        explored.append(successor)
                        sn = SearchNode(successor, action, cost, frontier,
                                        frontier.depth + 1)

                        # if stack.find(sn)
                        stack.push(sn)

        depth_limit += 1
        print(depth_limit)
        print(" ")
Пример #6
0
def solve(problem, heuristic):
    """ Return a list of directions. See handout for more details. """
    def priority_function(search_node):
        """ Return the priority f(search_node) """
        return search_node.path_cost + heuristic(search_node.state, problem)

    # The frontier is a PriorityQueueWithFunction (defined in frontiers.py).
    frontier = PQwF(priority_function)
    # Use SearchNode (defined in search_strategies.py) as the class of elements in frontier, and initialize frontier.
    node = SearchNode(problem.get_initial_state())
    frontier.push(node)

    explored = []  # The closed list (of states already explored).

    while not frontier.is_empty():
        # Check the first node in frontier.
        node = frontier.pop()
        if problem.goal_test(node.state):
            break

        # Expand this node if it is not the goal.
        for successor, action, cost in problem.get_successors(node.state):
            # Avoid revisiting the explored states.
            if successor in explored:
                continue
            else:
                explored.append(successor)
                # Add the successor node to frontier.
                frontier.push(
                    SearchNode(state=successor,
                               action=action,
                               path_cost=node.path_cost + cost,
                               parent=node,
                               depth=node.depth + 1))

    # Obtain the path from start state to the goal, by the attribute parent of SearchNode.
    path = []
    while node.parent:
        path.append(node.action)
        node = node.parent
    path.reverse()

    return path
Пример #7
0
def solve(problem, heuristic):
    """ *** YOUR CODE HERE *** """
    # util.raise_not_defined() #Remove this line when you have implemented BrFS

    frontier = PriorityQueue()
    s0 = problem.get_initial_state()
    closedSet = set()
    # closedSet.add(s0)
    openSet = set()
    openSet.add(s0)
    sn_root = SearchNode(s0)
    frontier.push(sn_root, heuristic(s0, problem))
    gScore = {}
    gScore[s0] = 0

    check = None
    while not frontier.is_empty():
        current_node = frontier.pop()
        # print(current_node.path_cost + heuristic(current_node.state,problem))
        closedSet.add(current_node.state)
        openSet.discard(current_node.state)
        check = check_goal(current_node, problem)

        if check == None:
            for successor, action, cost in problem.get_successors(
                    current_node.state):
                if successor not in closedSet:
                    tentative_gScore = current_node.path_cost + cost
                    if successor not in openSet:
                        openSet.add(successor)
                    #if there is a path that can be reached to this node more efficiently, discard this successor
                    elif tentative_gScore >= gScore[successor]:
                        continue
                    gScore[successor] = tentative_gScore
                    sn = SearchNode(successor, action, tentative_gScore,
                                    current_node, current_node.depth + 1)
                    # push this node to the Queue with gScore and hScore(caluculated by heuristic function)
                    frontier.push(sn,
                                  sn.path_cost + heuristic(successor, problem))
                    # total = sn.path_cost + heuristic(successor,problem)
                    # print(str(current_node.state) + "TO" + str(successor) + " path_cost=" + str(sn.path_cost) + " heuristic=" + str(heuristic(successor,problem)) + " total=" + str(total))
        else:
            return check
Пример #8
0
def dls(problem, limit):
    # *** YOUR CODE HERE ***
    frontiers = Stack()
    s0 = problem.get_initial_state()
    #initiate the frontier by the start point
    #state,action,cost,parent,depth
    a = SearchNode(s0)
    frontiers.push(a)

    while not frontiers.is_empty():
        cur = frontiers.pop()
        #goal_test
        if problem.goal_test(cur.state):
            return route(cur)
        if cur.depth != limit:
            #add frontiers
            for successor, action, cost in problem.get_successors(cur.state):
                b = SearchNode(successor, action, cur.path_cost + cost, cur,
                               cur.depth + 1)
                if valid_node(b):
                    frontiers.push(b)
Пример #9
0
def solve(problem):
    """ *** YOUR CODE HERE *** """
    # util.raise_not_defined() #Remove this line when you have implemented BrFS

    depth_limit = 0
    s0 = problem.get_initial_state()
    sn_root = SearchNode(s0)

    check = None
    while True:
        frontier = Stack()
        frontier.push(sn_root)

        while not frontier.is_empty():

            current_node = frontier.pop()
            #check if this node is the goal or not
            check = check_goal(current_node, problem)

            if check != None:  #if check != None: reached goal, so "check" contains the path
                return check
            else:
                if (current_node.depth == depth_limit):
                    continue
                for successor, action, cost in problem.get_successors(
                        current_node.state):
                    # if the successor is not explored yet, append this new successor to the explored dictionary
                    tmp = current_node
                    flag = True
                    while tmp.parent != None:
                        if successor == tmp.parent.state:
                            flag = False
                            break
                        tmp = tmp.parent
                    if flag:
                        sn = SearchNode(successor, action, cost, current_node,
                                        current_node.depth + 1)
                        frontier.push(sn)
        print("depth limit = " + str(depth_limit))
        depth_limit += 1
Пример #10
0
def solve(problem) :
    """ *** YOUR CODE HERE *** """
    # util.raise_not_defined() #Remove this line when you have implemented BrFS

    #iterative implementation of BFS
    frontier = Queue()
    s0 = problem.get_initial_state()
    explored = set()
    explored.add(s0)
    sn_root = SearchNode(s0)
    frontier.push(sn_root)
    check = None
    while not frontier.is_empty():
        current_node = frontier.pop()
        explored.add(current_node.state)
        check = check_goal(current_node, problem)
        if check == None:
            for successor, action, cost in problem.get_successors(current_node.state):
                if successor not in explored:
                    sn = SearchNode(successor, action, cost, current_node, current_node.depth + 1)
                    frontier.push(sn)
        else:
            return check
Пример #11
0
def dls_search(problem, depth_limit):
    # The frontier is a Stack (defined in frontiers.py), for its LIFO queuing policy.
    frontier = Stack()
    # Use SearchNode (defined in search_strategies.py) as the class of elements in frontier, and initialize frontier.
    frontier.push(SearchNode(problem.get_initial_state()))

    explored = []  # The closed list (of nodes already explored).

    while not frontier.is_empty():
        # Check the first node in frontier.
        node = frontier.pop()
        if problem.goal_test(node.state): return node
        if node.depth == depth_limit: continue

        for point in explored[::]:
            if point.depth > node.depth:
                explored.remove(point)

        # Expand this node if it is not the goal, nor does it reach the depth_limit.
        for successor, action, cost in problem.get_successors(node.state):
            # Avoid revisiting the explored states.
            if successor in [x.state for x in explored]:
                continue
            else:
                new_node = SearchNode(state=successor,
                                      action=action,
                                      path_cost=node.path_cost + cost,
                                      parent=node,
                                      depth=node.depth + 1)

                # Add the successor node to frontier and explored.
                frontier.push(new_node)
                explored.append(new_node)

    else:
        print(depth_limit)
        return 'cutoff'
Пример #12
0
def solve(problem):
    """ Return a list of directions. See handout for more details. """
    depth_limit = 0
    path = []  # The output path.
    while True:
        print('Optimal lower bound: {}'.format(depth_limit))

        # The closed list (of states already visited).
        # Note that it preserves the O(bm) space requirement.
        explored = []

        # Implement depth-limit search recursively.
        result = recursive_dls(SearchNode(problem.get_initial_state()),
                               problem, depth_limit, explored, path)
        if result == 'cutoff':
            depth_limit += 1
        elif result == 'success':
            path.reverse()
            return path
        else:  # result == 'failure', which means the goal is unreachable.
            print('Unreachable!')
            return None
Пример #13
0
def recursive_dfs(node, problem, path, depth, touched):
    # Set the notification of cutoff
    cutoff_occurred = False
    touched.add(node.state)
    # Test whether find the goal
    if problem.goal_test(node.state):
        path.append([node.state, node.action])
        actions = []
        while node.action is not None:
            actions.append(node.action)
            node = node.parent
        actions.reverse()
        return actions

    # Return cutoff if depth achieve limit
    if depth == 0:
        touched.remove(node.state)
        return cutoff
    else:
        # Put the state and action into path and recursive dfs to find the goal
        path.append([node.state, node.action])
        for successor, action, cost in problem.get_successors(node.state):
            if successor not in touched:
                # Create the child node
                tem = SearchNode(successor, action, node.path_cost + cost,
                                 node, depth)
                result = recursive_dfs(tem, problem, path, depth - 1, touched)
                if result == cutoff:
                    cutoff_occurred is True
                elif result is not None:
                    return result
        path.pop(-1)
        touched.remove(node.state)
        # Return cutoff if cutoff show up
        if cutoff_occurred is not True:
            return cutoff
        else:
            return