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