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