@@ -682,15 +682,12 @@ def _depth_first_search_adjacency_list(
682682
683683_depth_first_search_adjacency_matrix = _depth_first_search_adjacency_list
684684
685- def shortest_paths (graph : Graph , algorithm : str ,
686- source : str , target : str = "" ,
687- ** kwargs ) -> tuple :
685+ def shortest_paths (graph : Graph , algorithm : str , source : str , target : str = "" , ** kwargs ) -> tuple :
688686 """
689687 Finds shortest paths in the given graph from a given source.
690688
691689 Parameters
692690 ==========
693-
694691 graph: Graph
695692 The graph under consideration.
696693 algorithm: str
@@ -700,8 +697,10 @@ def shortest_paths(graph: Graph, algorithm: str,
700697 'bellman_ford' -> Bellman-Ford algorithm as given in [1].
701698
702699 'dijkstra' -> Dijkstra algorithm as given in [2].
700+
701+ 'A_star' -> A* algorithm as given in [3].
703702 source: str
704- The name of the source the node.
703+ The name of the source node.
705704 target: str
706705 The name of the target node.
707706 Optional, by default, all pair shortest paths
@@ -713,35 +712,12 @@ def shortest_paths(graph: Graph, algorithm: str,
713712
714713 Returns
715714 =======
716-
717715 (distances, predecessors): (dict, dict)
718716 If target is not provided and algorithm used
719- is 'bellman_ford'/'dijkstra'.
717+ is 'bellman_ford'/'dijkstra'/'A_star' .
720718 (distances[target], predecessors): (float, dict)
721719 If target is provided and algorithm used is
722- 'bellman_ford'/'dijkstra'.
723-
724- Examples
725- ========
726-
727- >>> from pydatastructs import Graph, AdjacencyListGraphNode
728- >>> from pydatastructs import shortest_paths
729- >>> V1 = AdjacencyListGraphNode("V1")
730- >>> V2 = AdjacencyListGraphNode("V2")
731- >>> V3 = AdjacencyListGraphNode("V3")
732- >>> G = Graph(V1, V2, V3)
733- >>> G.add_edge('V2', 'V3', 10)
734- >>> G.add_edge('V1', 'V2', 11)
735- >>> shortest_paths(G, 'bellman_ford', 'V1')
736- ({'V1': 0, 'V2': 11, 'V3': 21}, {'V1': None, 'V2': 'V1', 'V3': 'V2'})
737- >>> shortest_paths(G, 'dijkstra', 'V1')
738- ({'V2': 11, 'V3': 21, 'V1': 0}, {'V1': None, 'V2': 'V1', 'V3': 'V2'})
739-
740- References
741- ==========
742-
743- .. [1] https://en.wikipedia.org/wiki/Bellman%E2%80%93Ford_algorithm
744- .. [2] https://en.wikipedia.org/wiki/Dijkstra%27s_algorithm
720+ 'bellman_ford'/'dijkstra'/'A_star'.
745721 """
746722 raise_if_backend_is_not_python (
747723 shortest_paths , kwargs .get ('backend' , Backend .PYTHON ))
@@ -811,6 +787,49 @@ def _dijkstra_adjacency_list(graph: Graph, start: str, target: str):
811787
812788_dijkstra_adjacency_matrix = _dijkstra_adjacency_list
813789
790+ def _a_star_adjacency_list (graph : Graph , source : str , target : str ) -> tuple :
791+ distances , predecessor = {}, {}
792+
793+ for v in graph .vertices :
794+ distances [v ] = float ('inf' )
795+ predecessor [v ] = None
796+ distances [source ] = 0
797+
798+ from pydatastructs .miscellaneous_data_structures .queue import PriorityQueue
799+ pq = PriorityQueue (implementation = 'binomial_heap' )
800+ pq .push (source , 0 )
801+
802+ def heuristic (node : str , goal : str ) -> float :
803+ try :
804+ x1 , y1 = map (int , node .split (',' ))
805+ x2 , y2 = map (int , goal .split (',' ))
806+ return abs (x1 - x2 ) + abs (y1 - y2 )
807+ except ValueError :
808+ raise ValueError (f"Invalid node format: { node } . Expected 'x,y'." )
809+
810+ while not pq .is_empty :
811+ current = pq .pop ()
812+
813+ if current == target :
814+ return (distances [target ], predecessor )
815+
816+ neighbors = graph .neighbors (current )
817+ for neighbor in neighbors :
818+ edge = graph .get_edge (current , neighbor .name )
819+ if edge :
820+ new_dist = distances [current ] + edge .value
821+ if new_dist < distances [neighbor .name ]:
822+ distances [neighbor .name ] = new_dist
823+ predecessor [neighbor .name ] = current
824+ pq .push (neighbor .name , new_dist + heuristic (neighbor .name , target ))
825+
826+ if distances [target ] == float ('inf' ):
827+ raise ValueError (f"Either source '{ source } ' and target '{ target } ' have no path between them." )
828+
829+ return (distances , predecessor )
830+
831+ _a_star_adjacency_matrix = _a_star_adjacency_list
832+
814833def all_pair_shortest_paths (graph : Graph , algorithm : str ,
815834 ** kwargs ) -> tuple :
816835 """
0 commit comments