Lecture Notes on 25 April 2014 class Stack (object): def __init__ (self): self.stack = [] # add an item to the top of the stack def push (self, item): self.stack.append ( item ) # remove an item from the top of the stack def pop (self): return self.stack.pop() # check what item is on top of the stack without removing it def peek (self): return self.stack[len(self.stack) - 1] # check if a stack is empty def isEmpty (self): return (len(self.stack) == 0) # return the number of elements in the stack def size (self): return (len(self.stack)) class Queue (object): def __init__ (self): self.queue = [] def enqueue (self, item): self.queue.append (item) def dequeue (self): return (self.queue.pop(0)) def isEmpty (self): return (len (self.queue) == 0) def size (self): return len (self.queue) class Vertex (object): def __init__ (self, label): self.label = label self.visited = False # determine if vertex was visited def wasVisited (self): return self.visited # determine the label of the vertex def getLabel (self): return self.label # string representation of the vertex def __str__ (self): return str (self.label) class Graph (object): def __init__ (self): self.Vertices = [] self.adjMat = [] # check if a vertex already exists def hasVertex (self, label): nVert = len (self.Vertices) for i in range (nVert): if (label == (self.Vertices[i]).label): return True return False # given a label get the index def getIndex (self, label): nVert = len (self.Vertices) for i in range (nVert): if ((self.Vertices[i]).getLabel() == label): return i return -1 # add a vertex with a given label def addVertex (self, label): if not self.hasVertex (label): self.Vertices.append (Vertex (label)) # add a new column in the adjacency matrix for the new Vertex nVert = len (self.Vertices) for i in range (nVert - 1): (self.adjMat[i]).append (0) # add a new row for the new Vertex in the adjacency matrix newRow = [] for i in range (nVert): newRow.append (0) self.adjMat.append (newRow) # add weighted directed edge to graph def addDirectedEdge (self, start, finish, weight = 1): self.adjMat[start][finish] = weight # add weighted undirected edge to graph def addUndirectedEdge (self, start, finish, weight = 1): self.adjMat[start][finish] = weight self.adjMat[finish][start] = weight # return an unvisited vertex adjacent to vertex v def getAdjUnvisitedVertex (self, v): nVert = len (self.Vertices) for i in range (nVert): if (self.adjMat[v][i] > 0) and (not (self.Vertices[i]).wasVisited()): return i return -1 # do a depth first search in a graph def dfs (self, v): # create a stack theStack = Stack() # mark the vertex as visited and push on the stack (self.Vertices[v]).visited = True print (self.Vertices[v]) theStack.push (v) while (not theStack.isEmpty()): # get an adjacent unvisited vertex u = self.getAdjUnvisitedVertex (theStack.peek()) if (u == -1): u = theStack.pop() else: (self.Vertices[u]).visited = True print (self.Vertices[u]) theStack.push (u) # the stack is empty, reset the flags nVert = len (self.Vertices) for i in range (nVert): (self.Vertices[i]).visited = False # do a breadth first search in the graph def bfs (self, v): # create a queue theQueue = Queue() # mark the vertex as visited and enqueue (self.Vertices[v]).visited = True print (self.Vertices[v]) theQueue.enqueue (v) while (not theQueue.isEmpty()): # get the vertex at the front v1 = theQueue.dequeue() # get an adjacent unvisited vertex v2 = self.getAdjUnvisitedVertex (v1) while (v2 != -1): (self.Vertices[v2]).visited = True print (self.Vertices[v2]) theQueue.enqueue (v2) v2 = self.getAdjUnvisitedVertex (v1) # queue is empty, reset the flags nVert = len (self.Vertices) for i in range (nVert): (self.Vertices[i]).visited = False def main(): # create a Graph object cities = Graph() # open file for reading inFile = open ("./graph.txt", "r") # read the vertices numVertices = int ((inFile.readline()).strip()) print (numVertices) for i in range (numVertices): city = (inFile.readline()).strip() print (city) cities.addVertex (city) # read the edges numEdges = int ((inFile.readline()).strip()) print (numEdges) for i in range (numEdges): edge = (inFile.readline()).strip() print (edge) edge = edge.split() start = int (edge[0]) finish = int (edge[1]) weight = int (edge[2]) cities.addDirectedEdge (start, finish, weight) # print the adjacency matrix print ('\nAdjacency Matrix') for i in range (numVertices): for j in range (numVertices): print (cities.adjMat[i][j], end = ' ') print () print() # read the starting vertex for dfs and bfs startVertex = (inFile.readline()).strip() print (startVertex) # close file inFile.close() # get index of the start vertex startIndex = cities.getIndex (startVertex) print (startIndex) # do depth first search print ("\nDepth First Search from " + startVertex) cities.dfs (startIndex) print() # do breadth first search print ("Breadth First Search from " + startVertex) cities.bfs (startIndex) print() main()