# Name: Rushil Umaretiya # Date: 09/18/2020 # Each Vertex object will have attributes to store its own name and its list of its neighboring vertices. class Vertex: def __init__(self, name, vertices): self.name = name self.vertices = vertices def __str__(self): return f'{self.name} {self.vertices}' def __repr__(self): return str(self.name) # If the file exists, read all edges and build a graph. It returns a list of Vertexes. def build_graph(filename): try: file = open(filename, 'r') except: return [] lines = file.read().strip().splitlines() vertices = [] # Sorry about this solution Ms. Kim, it's not very efficient, but it makes sense. # Create all the source verticies for line in lines: line = line.strip().split() for vertex in vertices: if vertex.name == line[0]: break else: vertices.append(Vertex(line[0], [])) # Create all the ending verticies for line in lines: line = line.strip().split() for vertex in vertices: if vertex.name == line[1]: break else: vertices.append(Vertex(line[1], [])) # Link them! for line in lines: line = line.strip().split() source, end = None, None for vertex in vertices: if vertex.name == line[0]: source = vertex if vertex.name == line[1]: end = vertex if source != None and end != None: break source.vertices.append(end) return vertices # prints all vertices and adjacent lists of the given graph. def display_graph(graph): for vertex in graph: print (vertex) # checks if two Vertexes are reachable or not. def is_reachable(fromV, toV, graph): visited = [] Q = [fromV] while len(Q) > 0: state = Q.pop(0) if state not in visited: if state == toV: return True visited.append(state) neighbours = state.vertices for neighbour in neighbours: Q.append(neighbour) return False # returns the length of the path from a Vertex to the other Vertex. # If the other Vertex is not reachable, return -1. (Ex) Path cost of A to B to C is 2. def path_cost(fromV, toV, graph): if fromV == toV: return 0 if not is_reachable(fromV, toV, graph): return -1 visited = [] Q = [fromV] while len(Q) > 0: state = Q.pop(0) if state not in visited: if state == toV: return len(visited) visited.append(state) neighbours = state.vertices for neighbour in neighbours: Q.append(neighbour) # Test cases g = build_graph(input("filename: ")) # build a graph # To check if you build the graph with object correctly for v in g: print (v, v.vertices) display_graph(g) # display the graph (edge list) fromV, toV = None, None print ("If you want to stop checking, type -1 for vertex values") fromV_val, toV_val = input("From vertex value: "), input("To vertex value: ") # Get vertex values from user while fromV_val != '-1': # Find from and to Vertexes at graph for v in g: if v.name == fromV_val: fromV = v if v.name == toV_val: toV = v if fromV is None or toV is None: print ("One or more vertex value does not exist.") else: print ("From {} to {} is reachable?".format(fromV_val, toV_val), is_reachable(fromV, toV, g)) print ("Path cost from {} to {} is".format(fromV_val, toV_val), path_cost(fromV, toV, g)) # Reset to test another case fromV_val, toV_val = input("\nFrom vertex value: "), input("To vertex value: ") fromV, toV = None, None