def DFSRoute(graph, startVert, goalVert):
    """This algorithm searches a graph using depth-first search
    looking for a path from some start vertex to some goal vertex
    It uses a stack to store the indices of vertices that it still
    needs to examine."""

    if startVert == goalVert:
        return []
    s = Stack()
    s.push(startVert)
    visited = {startVert}
    pred = {startVert: None}
    while not s.isEmpty():
        nextVert = s.top()
        s.pop()
        neighbors = graph.getNeighbors(nextVert)
        for n in neighbors:
            if type(n) != int:
                # weighted graph, strip and ignore weights
                n = n[0]
            if n not in visited:
                visited.add(n)
                pred[n] = nextVert
                if n != goalVert:
                    s.push(n)
                else:
                    return reconstructPath(startVert, goalVert, pred)
    return "NO PATH"
Beispiel #2
0
 def _setupFringe(self, startState):
     """This method sets up the proper kind of fringe set for this particular search.
     In this case, it creates either a Queue or a Stack, depending on whether we are doing
     BFS or DFS, and it inserts the start state into it."""
     if self.mode == "BFS":
         self.fringe = Queue()
     else:
         self.fringe = Stack()
     self.fringe.insert(startState)
Beispiel #3
0
def DFSRoute(graph, startVert, goalVert):
    if startVert == goalVert:
        return []
    s = Stack()
    s.push(startVert)
    visited = [startVert]
    pred = {startVert: None}
    while not s.isEmpty():
#        print s
        nextVert = s.top()
        s.pop()
#        print "Examining vertex", nextVert
        neighbors = graph.getNeighbors(nextVert)
        for n in neighbors:
            if not n in visited:
#                print "     Adding neighbor", n, "to the fringe"
                visited.append(n)
                pred[n] = nextVert        
                if n == goalVert:
                    return reconstructPath(startVert, goalVert, pred)
                s.push(n)
    return "NO PATH"
Beispiel #4
0
class NoCostSearchSolver(AbstractSearchSolver):
    """This class contains a stack or queue search algorithm, so that it can do either BFS or DFS depending on whether
    it is instructed to use a stack or queue. This class contains stubs for the helper methods that those algorithms
    need.  Only the isGoal and generateNeighbors methods should be overridden by the subclass.  BFS is not
    guaranteed to give the best solution on a weighted graph, though it will always give the solution with the least
    edges.  DFS is not guaranteed to give the best solution, ever, but it is more memory-efficient.
    These algorithms assume that the states implement the comparison operators correctly!"""
    def __init__(self, taskAdvisor, mode='BFS'):
        """Takes in the task advisor, and an optional mode, which selects DFS or BFS.
        Sets up the qData needed for the search, the fringe and visited sets, and the counts of
        how many nodes were created and visited. The only generic qData are instance variables that count
        the number of nodes created and the number of nodes visited (that corresponds more or less to the
        number of nodes added to the queue and the number of nodes removed from the queue (and not found to be
        redundant))."""
        AbstractSearchSolver.__init__(self, taskAdvisor)
        self.mode = mode

    def _setupFringe(self, startState):
        """This method sets up the proper kind of fringe set for this particular search.
        In this case, it creates either a Queue or a Stack, depending on whether we are doing
        BFS or DFS, and it inserts the start state into it."""
        if self.mode == "BFS":
            self.fringe = Queue()
        else:
            self.fringe = Stack()
        self.fringe.insert(startState)

    def searchStep(self):
        """This method performs one step of a stack or queue search. It finds the next node in
        the stack/queue, generates its children, and adds the appropriate ones to the stack/queue.
        It returns three values: the current state, the neighbors of the current state, and a status
        message.  The message is either "Done", "Fail", or "Step" for a normal step."""
        newNeighbors = []
        if self.fringe.isEmpty():
            return (False, False, "Fail")
        nextState = self.fringe.delete()
        if self.taskAdvisor.isGoal(nextState):
            return (nextState, [], "Done"
                    )  # when hit goal, neighbors are irrelevant

        # Otherwise, go one
        if verbose:
            print("----------------------")
            print("Current state:", nextState)
        neighbors = self.taskAdvisor.generateNeighbors(nextState)
        self.visited.add(nextState)
        self.nodesVisited += 1

        for n in neighbors:
            visitedMatch = self._hasBeenVisited(n)
            fringeMatch = self._hasBeenFringed(n)

            if (not visitedMatch) and (not fringeMatch):
                if verbose:
                    print("    Neighbor never seen before", n)
                # this node has not been generated before, add it to the fringe
                self.fringe.insert(n)
                newNeighbors.append(n)
                self.nodesCreated += 1
            elif visitedMatch:
                if verbose:
                    print("    Neighbor was already in explored, skipping", n)
            elif fringeMatch:
                if verbose:
                    print("    Neighbor was already in fringe, skipping", n)

        # end for
        return nextState, newNeighbors, "Not Done"