@@ -697,11 +697,9 @@ def shortest_paths(graph: Graph, algorithm: str,
697697 The algorithm to be used. Currently, the following algorithms
698698 are implemented,
699699
700- 'bellman_ford' -> Bellman-Ford algorithm as given in [1].
700+ 'bellman_ford' -> Bellman-Ford algorithm as given in [1], with a queue to improve performance on sparse graphs .
701701
702702 'dijkstra' -> Dijkstra algorithm as given in [2].
703-
704- 'queue_improved_bellman_ford' -> Queue Improved Bellman-Ford algorithm as given in [3].
705703 source: str
706704 The name of the source the node.
707705 target: str
@@ -744,7 +742,6 @@ def shortest_paths(graph: Graph, algorithm: str,
744742
745743 .. [1] https://en.wikipedia.org/wiki/Bellman%E2%80%93Ford_algorithm
746744 .. [2] https://en.wikipedia.org/wiki/Dijkstra%27s_algorithm
747- .. [3] https://en.wikipedia.org/wiki/Bellman%E2%80%93Ford_algorithm#Improvements
748745 """
749746 raise_if_backend_is_not_python (
750747 shortest_paths , kwargs .get ('backend' , Backend .PYTHON ))
@@ -757,27 +754,34 @@ def shortest_paths(graph: Graph, algorithm: str,
757754 return getattr (algorithms , func )(graph , source , target )
758755
759756def _bellman_ford_adjacency_list (graph : Graph , source : str , target : str ) -> tuple :
760- distances , predecessor = {}, {}
757+ distances , predecessor , visited , cnts = {}, {}, {}, {}
761758
762759 for v in graph .vertices :
763760 distances [v ] = float ('inf' )
764761 predecessor [v ] = None
762+ visited [v ] = False
763+ cnts [v ] = 0
765764 distances [source ] = 0
765+ verticy_num = len (graph .vertices )
766766
767- edges = graph .edge_weights .values ()
768- for _ in range (len (graph .vertices ) - 1 ):
769- for edge in edges :
770- u , v = edge .source .name , edge .target .name
771- w = edge .value
772- if distances [u ] + edge .value < distances [v ]:
773- distances [v ] = distances [u ] + w
774- predecessor [v ] = u
767+ que = Queue ([source ])
775768
776- for edge in edges :
777- u , v = edge .source .name , edge .target .name
778- w = edge .value
779- if distances [u ] + w < distances [v ]:
780- raise ValueError ("Graph contains a negative weight cycle." )
769+ while que :
770+ u = que .popleft ()
771+ visited [u ] = False
772+ neighbors = graph .neighbors (u )
773+ for neighbor in neighbors :
774+ v = neighbor .name
775+ edge_str = u + '_' + v
776+ if distances [u ] != float ('inf' ) and distances [u ] + graph .edge_weights [edge_str ].value < distances [v ]:
777+ distances [v ] = distances [u ] + graph .edge_weights [edge_str ].value
778+ predecessor [v ] = u
779+ cnts [v ] = cnts [u ] + 1
780+ if cnts [v ] >= verticy_num :
781+ raise ValueError ("Graph contains a negative weight cycle." )
782+ if not visited [v ]:
783+ que .append (v )
784+ visited [v ] = True
781785
782786 if target != "" :
783787 return (distances [target ], predecessor )
@@ -814,37 +818,6 @@ def _dijkstra_adjacency_list(graph: Graph, start: str, target: str):
814818
815819_dijkstra_adjacency_matrix = _dijkstra_adjacency_list
816820
817- def _queue_improved_bellman_ford_adjacency_list (graph : Graph , source : str , target : str ) -> tuple :
818- distances , predecessor , visited = {}, {}, {}
819-
820- for v in graph .vertices :
821- distances [v ] = float ('inf' )
822- predecessor [v ] = None
823- visited [v ] = False
824- distances [source ] = 0
825-
826- que = Queue ([source ])
827-
828- while que :
829- u = que .popleft ()
830- visited [u ] = False
831- neighbors = graph .neighbors (u )
832- for neighbor in neighbors :
833- v = neighbor .name
834- edge_str = u + '_' + v
835- if distances [u ] != float ('inf' ) and distances [u ] + graph .edge_weights [edge_str ].value < distances [v ]:
836- distances [v ] = distances [u ] + graph .edge_weights [edge_str ].value
837- predecessor [v ] = u
838- if not visited [v ]:
839- que .append (v )
840- visited [v ] = True
841-
842- if target != "" :
843- return (distances [target ], predecessor )
844- return (distances , predecessor )
845-
846- _queue_improved_bellman_ford_adjacency_matrix = _queue_improved_bellman_ford_adjacency_list
847-
848821def all_pair_shortest_paths (graph : Graph , algorithm : str ,
849822 ** kwargs ) -> tuple :
850823 """
0 commit comments