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"
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 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"
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"