From 523c27294c16004e65154f26fe411dc5f8ee0579 Mon Sep 17 00:00:00 2001 From: Pulkit Mishra Date: Tue, 29 Oct 2019 03:38:18 +0530 Subject: [PATCH] Adds Floyd Warshall Algorithm --- graphing/floyd_warshall.py | 142 +++++++++++++++++++++++++++++++++++++ 1 file changed, 142 insertions(+) create mode 100644 graphing/floyd_warshall.py diff --git a/graphing/floyd_warshall.py b/graphing/floyd_warshall.py new file mode 100644 index 0000000..bae93d8 --- /dev/null +++ b/graphing/floyd_warshall.py @@ -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 ') +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