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 ') print('add edge ') 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