예제 #1
0
def graph_search(problem, verbose=False, debug=False):
    """graph_search(problem, verbose, debug) - Given a problem representation
    (instance of basicsearch_lib02.representation.Problem or derived class),
    attempt to solve the problem.
    
    If debug is True, debugging information will be displayed.
    
    if verbose is True, the following information will be displayed:
        
        Number of moves to solution
        List of moves and resulting puzzle states
        Example:
        
            Solution in 25 moves        
            Initial state
                  0        1        2    
            0     4        8        7    
            1     5        .        2    
            2     3        6        1    
            Move 1 -  [0, -1]
                  0        1        2    
            0     4        8        7    
            1     .        5        2    
            2     3        6        1    
            Move 2 -  [1, 0]
                  0        1        2    
            0     4        8        7    
            1     3        5        2    
            2     .        6        1    
            
            ... more moves ...
            
                  0        1        2    
            0     1        3        5    
            1     4        2        .    
            2     6        7        8    
            Move 22 -  [-1, 0]
                  0        1        2    
            0     1        3        .    
            1     4        2        5    
            2     6        7        8    
            Move 23 -  [0, -1]
                  0        1        2    
            0     1        .        3    
            1     4        2        5    
            2     6        7        8    
            Move 24 -  [1, 0]
                  0        1        2    
            0     1        2        3    
            1     4        .        5    
            2     6        7        8    
        
        If no solution were found (not possible with the puzzles we
        are using), we would display:
        
            No solution found
    
    Returns a tuple (path, nodes_explored) where:
    path - list of actions to solve the problem or None if no solution was found
    nodes_explored - Number of nodes explored (dequeued from frontier)
    """

    frontierNodes = PriorityQueue(min, Node.get_f)
    node = Node(problem, problem.getInitialBoardState())
    nodesExplored = 0

    exploredStates = Explored()  #hash table to store states
    exploredStates.add(node)

    for node in node.expand(problem):
        if not exploredStates.exists(node):  #its not a duplicate in explored
            frontierNodes.append(node)  #get initial frontier nodes

    done = found = False

    while not done:
        node = frontierNodes.pop()  #loop thru frontier states
        nodesExplored += 1
        exploredStates.add(node)

        if problem.goal_test(node.state):  #if found, set true
            found = done = True

        else:  #if not, then add the new frontier states to the queue
            for node in node.expand(problem):
                if not exploredStates.exists(
                        node):  #its not a duplicate in explored
                    #if not frontierNodes.__contains__(node): #not a duplicate in frontier, slow!
                    frontierNodes.append(node)

            if (frontierNodes.__len__ == 0
                ):  #if we run thru all frontier, search complete
                done = True

    if found:
        if (verbose):
            print("Moves to solution: ", node.path().__len__())
            print("Nodes Expanded: ", nodesExplored)

            move = 0
            solutionList = node.solution()
            boardList = []

            for node in node.path():
                boardList.append(problem.generateDebugBoard(node.state))

            print("Initial State")
            for board in boardList:
                counter = move + 1
                print(board)
                print()
                if (move < boardList.__len__() - 1):
                    print("Move ", counter, " ", solutionList[move])
                move += 1

        if (debug):
            print()
            print("Debug Info:")
            print(print_nodes(node.path()))
            print()

        return (node.solution(), nodesExplored
                )  #returns solution node's path/solution
    else:
        if (verbose | debug):
            print("No solution found")
        return ("No solution found", nodesExplored)
예제 #2
0
def graph_search(problem, verbose=False, debug=False):
    """graph_search(problem, verbose, debug) - Given a problem representation
    (instance of basicsearch_lib02.representation.Problem or derived class),
    attempt to solve the problem.
    
    If debug is True, debugging information will be displayed.
    
    if verbose is True, the following information will be displayed:
        
        Number of moves to solution
        List of moves and resulting puzzle states
        Example:
        
            Solution in 25 moves        
            Initial state
                  0        1        2    
            0     4        8        7    
            1     5        .        2    
            2     3        6        1    
            Move 1 -  [0, -1]
                  0        1        2    
            0     4        8        7    
            1     .        5        2    
            2     3        6        1    
            Move 2 -  [1, 0]
                  0        1        2    
            0     4        8        7    
            1     3        5        2    
            2     .        6        1    
            
            ... more moves ...
            
                  0        1        2    
            0     1        3        5    
            1     4        2        .    
            2     6        7        8    
            Move 22 -  [-1, 0]
                  0        1        2    
            0     1        3        .    
            1     4        2        5    
            2     6        7        8    
            Move 23 -  [0, -1]
                  0        1        2    
            0     1        .        3    
            1     4        2        5    
            2     6        7        8    
            Move 24 -  [1, 0]
                  0        1        2    
            0     1        2        3    
            1     4        .        5    
            2     6        7        8    
        
        If no solution were found (not possible with the puzzles we
        are using), we would display:
        
            No solution found
    
    Returns a tuple (path, nodes_explored) where:
    path - list of actions to solve the problem or None if no solution was found
    nodes_explored - Number of nodes explored (dequeued from frontier)
    """
    #Initial tileboard for testing
    tb = problem.initial
    #Create first node and test if node passes goal
    node0 = Node(problem, tb)
    if problem.goal_test(node0.state) == True:
        return node0.solution()
    #define frontier set as priority queue and the explored set
    pq = PriorityQueue()
    pq.append(node0)
    new_nodes = []
    exploredSet = Explored()
    frontier = Explored()
    frontier.add(node0)
    nodesExpanded = 0

    #Expand the search tree until the goal state is found
    found = False
    #time.sleep(2)
    while (not found):
        #Check if the frontier is empty signifying failure
        if pq.__len__() == 0:
            print("No solution found")
            break
        #Take the next node from the priority queue and add it to explored set
        node = pq.pop()
        exploredSet.add(node)
        #Check if the goal state has been found
        if problem.goal_test(node.state) == True:
            path = node.path()
            solution = node.solution()
            steps = len(path) - 1
            found = True
            if verbose == True:
                verboseFunc(solution, steps, tb, path)
        else:
            #Expand the search tree and check if the nodes have been explored
            new_nodes = node.expand(problem)
        for j in range(len(new_nodes)):
            if exploredSet.exists(new_nodes[j].state) or frontier.exists(
                    new_nodes[j].state):
                continue
            else:
                #Add one to the number of nodes explored
                nodesExpanded += 1
                pq.append(new_nodes[j])  #Add the nodes to the priority queue
                frontier.add(
                    new_nodes[j])  #use hashed set to decrease lookup time
                if debug == True:
                    debugFunc(debug, pq)
    return (steps, nodesExpanded)
예제 #3
0
def graph_search(problem, verbose=False, debug=False):
    """graph_search(problem, verbose, debug) - Given a problem representation
    (instance of basicsearch_lib02.representation.Problem or derived class),
    attempt to solve the problem.
    
    If debug is True, debugging information will be displayed.
    
    if verbose is True, the following information will be displayed:
        
        Number of moves to solution
        List of moves and resulting puzzle states
        Example:
        
            Solution in 25 moves        
            Initial state
                  0        1        2    
            0     4        8        7    
            1     5        .        2    
            2     3        6        1    
            Move 1 -  [0, -1]
                  0        1        2    
            0     4        8        7    
            1     .        5        2    
            2     3        6        1    
            Move 2 -  [1, 0]
                  0        1        2    
            0     4        8        7    
            1     3        5        2    
            2     .        6        1    
            
            ... more moves ...
            
                  0        1        2    
            0     1        3        5    
            1     4        2        .    
            2     6        7        8    
            Move 22 -  [-1, 0]
                  0        1        2    
            0     1        3        .    
            1     4        2        5    
            2     6        7        8    
            Move 23 -  [0, -1]
                  0        1        2    
            0     1        .        3    
            1     4        2        5    
            2     6        7        8    
            Move 24 -  [1, 0]
                  0        1        2    
            0     1        2        3    
            1     4        .        5    
            2     6        7        8    
        
        If no solution were found (not possible with the puzzles we
        are using), we would display:
        
            No solution found
    
    Returns a tuple (path, nodes_explored) where:
    path - list of actions to solve the problem or None if no solution was found
    nodes_explored - Number of nodes explored (dequeued from frontier)
    """

    path = []
    nodes_explored = 0
    return_tuple = ()

    node = Node(problem, problem.initial)  # root node

    frontier = PriorityQueue(order=min,
                             f=lambda x: x.get_f())  # todo Sort this out
    explored = Explored()
    frontier.append(node)

    if problem.goal_test(node.state):
        path = node.solution()
        return_tuple = (path, nodes_explored)
        return return_tuple

    counter = 0

    while True:
        if frontier.__len__() == 0:
            path = node.solution()
            nodes_explored = counter
            return_tuple = (path, nodes_explored)
            return return_tuple
        node = frontier.pop()
        if problem.goal_test(node.state):
            break
        child_nodes = node.expand(problem)
        if explored.add(node.state):
            counter = counter + 1
        for child_node in child_nodes:
            if child_node not in frontier and not explored.exists(
                    child_node.state):
                frontier.append(child_node)

    path = node.solution()
    node_path = node.path()
    if verbose:
        print("Solution in " + str(len(node_path) - 1) + " moves.")
        i = 0
        for sol in node_path:
            if i is 0:
                print("Initial state")
                print(sol.state)
                i = i + 1
                continue
            print("Move " + str(i) + " - " + str(path[i - 1]))
            print(sol.state)
            i = i + 1
    nodes_explored = counter
    return_tuple = (path, nodes_explored)
    return return_tuple