Skip to content

Commit ff0d7c8

Browse files
committed
feat: add graph algorithem
1 parent e31ba9c commit ff0d7c8

File tree

1 file changed

+21
-15
lines changed

1 file changed

+21
-15
lines changed

pydatastructs/graphs/algorithms.py

Lines changed: 21 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -722,11 +722,11 @@ def shortest_paths(graph: Graph, algorithm: str, source: str, target: str="", **
722722
raise_if_backend_is_not_python(
723723
shortest_paths, kwargs.get('backend', Backend.PYTHON))
724724
import pydatastructs.graphs.algorithms as algorithms
725-
func = "_" + algorithm + "_" + graph._impl
726-
if algorithm not in ['bellman_ford', 'dijkstra', 'A_star']:
727-
raise NotImplementedError(f"Algorithm {algorithm} is not implemented.")
725+
func = "_" + algorithm.lower() + "_" + graph._impl
728726
if not hasattr(algorithms, func):
729-
raise NotImplementedError(f"Currently {algorithm} algorithm isn't implemented for finding shortest paths in graphs.")
727+
raise NotImplementedError(
728+
"Currently %s algorithm isn't implemented for "
729+
"finding shortest paths in graphs."%(algorithm))
730730
return getattr(algorithms, func)(graph, source, target)
731731

732732
def _bellman_ford_adjacency_list(graph: Graph, source: str, target: str) -> tuple:
@@ -797,22 +797,23 @@ def _a_star_adjacency_list(graph: Graph, source: str, target: str) -> tuple:
797797

798798
from pydatastructs.miscellaneous_data_structures.queue import PriorityQueue
799799
pq = PriorityQueue(implementation='binomial_heap')
800-
pq.push(source, distances[source] + heuristic(source, target)) # Fixed push
800+
pq.push(source, distances[source])
801801

802802
def heuristic(node: str, goal: str) -> float:
803+
"""Manhattan distance heuristic for A*"""
803804
try:
804-
x1, y1 = map(int, node.split(','))
805-
x2, y2 = map(int, goal.split(','))
806-
return abs(x1 - x2) + abs(y1 - y2)
805+
if "," in node and "," in goal: # Check if node names are in "x,y" format
806+
x1, y1 = map(int, node.split(','))
807+
x2, y2 = map(int, goal.split(','))
808+
return abs(x1 - x2) + abs(y1 - y2)
809+
else:
810+
return 0 # If not in coordinate format, return 0 heuristic
807811
except ValueError:
808-
raise ValueError(f"Invalid node format: {node}. Expected 'x,y'.")
812+
return 0 # Fallback heuristic if parsing fails
809813

810814
while not pq.is_empty:
811815
current = pq.pop()
812816

813-
if current == target:
814-
return (distances[target], predecessor)
815-
816817
neighbors = graph.neighbors(current)
817818
for neighbor in neighbors:
818819
edge = graph.get_edge(current, neighbor.name)
@@ -823,10 +824,15 @@ def heuristic(node: str, goal: str) -> float:
823824
predecessor[neighbor.name] = current
824825
pq.push(neighbor.name, new_dist + heuristic(neighbor.name, target))
825826

826-
if distances[target] == float('inf'):
827-
raise ValueError(f"Either source '{source}' and target '{target}' have no path between them.")
827+
# ✅ Handle case when target is empty (all-pairs shortest paths)
828+
if target == "":
829+
return (distances, predecessor)
828830

829-
return (distances, predecessor)
831+
# ✅ Handle no path found case properly
832+
if target not in distances or distances[target] == float('inf'):
833+
return (float('inf'), predecessor)
834+
835+
return (distances[target], predecessor)
830836

831837
_a_star_adjacency_matrix = _a_star_adjacency_list # Ensure matrix version exists
832838

0 commit comments

Comments
 (0)