| 
						
						
						
					 | 
				
				 | 
				
					@ -0,0 +1,142 @@ | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					class Graph: | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    def __init__(self): | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        self.vertices = {} | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					  | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    def add_vertex(self, key): | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        vertex = Vertex(key) | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        self.vertices[key] = vertex | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					  | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    def get_vertex(self, key): | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        return self.vertices[key] | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					  | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    def __contains__(self, key): | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        return key in self.vertices | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					  | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    def add_edge(self, src_key, dest_key, weight=1): | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        self.vertices[src_key].add_neighbour(self.vertices[dest_key], weight) | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					  | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    def does_edge_exist(self, src_key, dest_key): | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        return self.vertices[src_key].does_it_point_to(self.vertices[dest_key]) | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					  | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    def __len__(self): | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        return len(self.vertices) | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					  | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    def __iter__(self): | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        return iter(self.vertices.values()) | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					  | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					  | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					class Vertex: | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    def __init__(self, key): | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        self.key = key | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        self.points_to = {} | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					  | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    def get_key(self): | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        return self.key | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					  | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    def add_neighbour(self, dest, weight): | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        self.points_to[dest] = weight | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					  | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    def get_neighbours(self): | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        return self.points_to.keys() | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					  | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    def get_weight(self, dest): | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        return self.points_to[dest] | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					  | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    def does_it_point_to(self, dest): | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        return dest in self.points_to | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					  | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					  | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					def floyd_warshall(g): | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    distance = {v:dict.fromkeys(g, float('inf')) for v in g} | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    next_v = {v:dict.fromkeys(g, None) for v in g} | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					  | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    for v in g: | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        for n in v.get_neighbours(): | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					            distance[v][n] = v.get_weight(n) | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					            next_v[v][n] = n | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					  | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    for v in g: | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					         distance[v][v] = 0 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					         next_v[v][v] = None | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					  | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    for p in g:  | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        for v in g: | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					            for w in g: | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                if distance[v][w] > distance[v][p] + distance[p][w]: | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                    distance[v][w] = distance[v][p] + distance[p][w] | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                    next_v[v][w] = next_v[v][p] | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					  | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    return distance, next_v | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					  | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					  | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					def print_path(next_v, u, v): | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					     | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    p = u | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    while (next_v[p][v]): | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        print('{} -> '.format(p.get_key()), end='') | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        p = next_v[p][v] | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    print('{} '.format(v.get_key()), end='') | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					  | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					  | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					g = Graph() | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					print('Menu') | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					print('add vertex <key>') | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					print('add edge <src> <dest> <weight>') | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					print('floyd-warshall') | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					print('display') | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					print('quit') | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					  | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					while True: | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    do = input('What would you like to do? ').split() | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					  | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    operation = do[0] | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    if operation == 'add': | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        suboperation = do[1] | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        if suboperation == 'vertex': | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					            key = int(do[2]) | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					            if key not in g: | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                g.add_vertex(key) | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					            else: | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                print('Vertex already exists.') | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        elif suboperation == 'edge': | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					            src = int(do[2]) | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					            dest = int(do[3]) | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					            weight = int(do[4]) | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					            if src not in g: | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                print('Vertex {} does not exist.'.format(src)) | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					            elif dest not in g: | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                print('Vertex {} does not exist.'.format(dest)) | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					            else: | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                if not g.does_edge_exist(src, dest): | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                    g.add_edge(src, dest, weight) | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                else: | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                    print('Edge already exists.') | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					  | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    elif operation == 'floyd-warshall': | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        distance, next_v = floyd_warshall(g) | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        print('Shortest distances:') | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        for start in g: | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					            for end in g: | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                if next_v[start][end]: | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                    print('From {} to {}: '.format(start.get_key(), | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                                                    end.get_key()), | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                            end = '') | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                    print_path(next_v, start, end) | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                    print('(distance {})'.format(distance[start][end])) | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					  | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    elif operation == 'display': | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        print('Vertices: ', end='') | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        for v in g: | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					            print(v.get_key(), end=' ') | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        print() | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					  | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        print('Edges: ') | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        for v in g: | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					            for dest in v.get_neighbours(): | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                w = v.get_weight(dest) | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                print('(src={}, dest={}, weight={}) '.format(v.get_key(), | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                                                             dest.get_key(), w)) | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        print() | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					  | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    elif operation == 'quit': | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        break |