def test_no_path(self): source = 2 target = 8 algorithm = Dijkstra(self.G) algorithm.run(source) distance_expected = { 0: float("inf"), 1: float("inf"), 2: 0, 3: 56, 4: 60, 5: 94, 6: 76, 7: 91, 8: float("inf") } self.assertEqual(algorithm.distance, distance_expected) parent_expected = { 0: None, 1: None, 2: None, 3: 2, 4: 3, 5: 6, 6: 3, 7: 6, 8: None } self.assertEqual(algorithm.parent, parent_expected) #path_expected = [] #self.assertEqual(algorithm.path(target), path_expected) self.assertRaises(ValueError, algorithm.path, target)
def test_shortest_path(self): source = 0 target = 7 algorithm = Dijkstra(self.G) algorithm.run(source) distance_expected = { 0: 0, 1: 65, 2: 100, 3: 134, 4: 138, 5: 172, 6: 154, 7: 169, 8: 106 } self.assertEqual(algorithm.distance, distance_expected) parent_expected = { 0: None, 1: 0, 2: 1, 3: 8, 4: 3, 5: 6, 6: 3, 7: 6, 8: 1 } self.assertEqual(algorithm.parent, parent_expected) path_expected = [0, 1, 8, 3, 6, 7] self.assertEqual(algorithm.path(target), path_expected)
def run(self): """Finding all shortest paths.""" # graph copy size = self.graph.v() self._new_graph = self.graph.__class__(size + 1, directed=True) for node in self.graph.iternodes(): # O(V) time self._new_graph.add_node(node) for edge in self.graph.iteredges(): # O(E) time self._new_graph.add_edge(edge) self._new_node = size self._new_graph.add_node(self._new_node) for node in self.graph.iternodes(): # O(V) time self._new_graph.add_edge(Edge(self._new_node, node, 0)) self._bf = BellmanFord(self._new_graph) # If this step detects a negative cycle, the algorithm is terminated. self._bf.run(self._new_node) # O(V*E) time # Edges are reweighted. for edge in list(self._new_graph.iteredges()): # O(E) time edge.weight = (edge.weight + self._bf.distance[edge.source] - self._bf.distance[edge.target]) self._new_graph.del_edge(edge) self._new_graph.add_edge(edge) # Remove _new_node with edges. self._new_graph.del_node(self._new_node) # Weights are modified! self.distance = dict() for source in self.graph.iternodes(): self.distance[source] = dict() algorithm = Dijkstra(self._new_graph) # O(V*E*log(V)) total time algorithm.run(source) for target in self.graph.iternodes(): # O(V^2) total time self.distance[source][target] = (algorithm.distance[target] - self._bf.distance[source] + self._bf.distance[target])
def test_dijkstra_for_path_not_found(self): print("Testing Matrix 2nd time") self.N = 8 # number of nodes self.G = Graph(self.N, directed=True) self.nodes = range(self.N) self.edges = [ Edge(0, 1, 65), Edge(1, 8, 41), Edge(1, 2, 35), Edge(2, 3, 56), Edge(3, 4, 4), Edge(3, 6, 20), Edge(5, 2, 30), Edge(6, 5, 18), Edge(6, 7, 15), Edge(8, 3, 28) ] for node in self.nodes: self.G.add_node(node) for edge in self.edges: self.G.add_edge(edge) # self.G.show() algorithm = Dijkstra(self.G) source = 0 algorithm.run(source) target = 7 path_expected = [0, 1, 8, 3, 6, 7] distance_expected = 169 self.assertEqual(path_expected, algorithm.path(target)) self.assertEqual(distance_expected, algorithm.distance[target]) algorithm2 = DijkstraMatrix(self.G) algorithm2.run(source) self.assertEqual(path_expected, algorithm.path(target)) self.assertEqual(distance_expected, algorithm.distance[target]) source = 2 target = 8 algorithm.run(source) try: algorithm.path(target) except: pass else: self.fail("Path exception was not raised!") algorithm2.run(source) try: algorithm2.path(target) except: pass else: self.fail("Path exception was not raised!")
def test_shortest_path(self): source = 0 target = 3 algorithm = Dijkstra(self.G) algorithm.run(source) distance_expected = {0: 0, 1: 1, 2: 2, 3: 3} self.assertEqual(algorithm.distance, distance_expected) parent_expected = {0: None, 2: 1, 1: 0, 3: 2} self.assertEqual(algorithm.parent, parent_expected) path_expected = [0, 1, 2, 3] self.assertEqual(algorithm.path(target), path_expected)
def test_shortest_path(self): print("Testing Dijkstra") source = 0 target = 3 algorithm = Dijkstra(self.G) algorithm.run(source) distance_expected = {0: 0, 1: 1, 2: 2, 3: 3} self.assertEqual(algorithm.distance, distance_expected) parent_expected = {0: None, 2: 1, 1: 0, 3: 2} self.assertEqual(algorithm.parent, parent_expected) path_expected = [0, 1, 2, 3] self.assertEqual(algorithm.path(target), path_expected)
def run(self): """Finding all shortest paths.""" if self.positive_weights: self._new_graph = self.graph else: # graph copy self._new_graph = self.graph.__class__(self.graph.v()+1, directed=True) for node in self.graph.iternodes(): # O(V) time self._new_graph.add_node(node) for edge in self.graph.iteredges(): # O(E) time self._new_graph.add_edge(edge) self._new_node = self.graph.v() self._new_graph.add_node(self._new_node) for node in self.graph.iternodes(): # O(V) time self._new_graph.add_edge(Edge(self._new_node, node, 0)) self._bf = BellmanFord(self._new_graph) # If this step detects a negative cycle, # the algorithm is terminated. self._bf.run(self._new_node) # O(V*E) time # Edges are reweighted. for edge in list(self._new_graph.iteredges()): # O(E) time edge.weight = (edge.weight + self._bf.distance[edge.source] - self._bf.distance[edge.target]) self._new_graph.del_edge(edge) self._new_graph.add_edge(edge) # Remove _new_node with edges. self._new_graph.del_node(self._new_node) self.distance = dict() for source in self.graph.iternodes(): self.distance[source] = dict() algorithm = Dijkstra(self._new_graph) # O(V*E*log(V)) total time algorithm.run(source) for target in self.graph.iternodes(): # O(V**2) total time if self.positive_weights: self.distance[source][target] = algorithm.distance[target] else: self.distance[source][target] = ( algorithm.distance[target] - self._bf.distance[source] + self._bf.distance[target])