A* algorithm and its Heuristic Search Strategy in AI

Last Updated : 25 Aug, 2026

The A* algorithm is highly effective and well-known search technique utilized for finding the most efficient path between two points in a graph. It is applied in scenarios such as pathfinding in video games, network routing and other AI applications.

  • Finds a path from a starting point to a destination.
  • Uses both the distance already traveled and an estimate of the distance remaining to choose the best path.

Components

A* uses two important parameters to find the cost of a path:

  1. g(n): Actual cost of reaching node n from the start node. This is the accumulated cost of the path from the start node to node n.
  2. h(n): The heuristic estimate of the cost to reach the goal from node n. This is a weighted guess about how much further it will take to reach the goal.

The function, f(n)=g(n)+h(n) is the total estimated cost of the cheapest solution through node n. This function combines the path cost so far and the heuristic cost to estimate the total cost guiding the search more efficiently.

Working

A* is an informed search algorithm that uses f(n), g(n) and h(n) to decide which node to explore next.

  1. Initialization: Add the start node to the open set and calculate its f(n) value.
  2. Select Node: Choose the node with the lowest f(n) value from the open set.
  3. Goal Check: If the selected node is the goal, reconstruct and return the path.
  4. Expand Node: Examine its neighboring nodes and calculate their f(n), g(n) and h(n) values.
  5. Update Costs: If a lower-cost path to a neighbor is found, update its cost and parent information and add it to the open set.
  6. Repeat: Continue until the goal is reached or the open set becomes empty.

Heuristic Function

The heuristic function h(n) estimates the cost from the current node to the goal. Its quality has a major effect on A*'s performance.

Properties of a Good Heuristic

  • Admissibility: A heuristic never guesses a cost higher than the actual cost to the goal. With non-negative edge costs, this allows A* to guarantee an optimal solution. For example, using straight-line distance on a map is an admissible heuristic.
  • Consistency (Monotonicity): A heuristic is consistent if its estimate satisfies the triangle inequality (h(n)\leq c(n, p) + h(p) for every node n and neighbor p). This ensures f(n) values never decrease along any path, allowing A* to process each node at most once without needing to recheck or re-open nodes in the Closed Set.

Note: Every consistent heuristic is automatically admissible, but not every admissible heuristic is consistent.

Common Heuristics

  • Manhattan Distance: It is used for grid-based environments where movement is restricted to horizontal and vertical directions. It calculates the sum of the absolute differences in the x and y coordinates between two points.
  • Euclidean Distance: The straight-line distance between two points often used when movement is allowed in any direction.
  • Chebyshev Distance: It is used when diagonal movement is allowed at the same cost as horizontal or vertical movement.

Implementation of Pathfinding Example using A* Algorithm

Consider a small weighted graph where each node represents a position and each edge represents a possible movement with an associated cost. The objective is to find a least-cost path from (0, 0) to (2, 2).

Step 1: Importing Required Libraries

Python
import heapq
import networkx as nx
import matplotlib.pyplot as plt
  • heapq: Provides a min-heap priority queue, used by A* to select the node with the lowest f(n) value.
  • networkx: Creates and manages the graph and its nodes and edges.
  • matplotlib.pyplot: Visualizes the graph and highlights the path found by A*.

Step 2: Defining Heuristic Function

Manhattan distance is used as the heuristic because the example uses coordinate-based movement with unit-cost horizontal and vertical edges.

Python
def heuristic(a, b):
    return abs(a[0] - b[0]) + abs(a[1] - b[1])

Step 3: Implementing A* Algorithm

The A* algorithm maintains an open_set priority queue and tracks the cost of reaching each node using g_score. It calculates f(n)=g(n)+h(n) and always expands the node with the lowest estimated total cost. The came_from dictionary stores parent nodes for reconstructing the final path.

Python
def a_star(graph, start, goal):
    open_set = []
    heapq.heappush(open_set, (0, start))
    came_from = {}
    g_score = {node: float('inf') for node in graph}
    g_score[start] = 0
    f_score = {node: float('inf') for node in graph}
    f_score[start] = heuristic(start, goal)

    while open_set:
        _, current = heapq.heappop(open_set)
        if current == goal:
            return reconstruct_path(came_from, current)

        for neighbor, cost in graph[current].items():
            tentative_g_score = g_score[current] + cost
            if tentative_g_score < g_score[neighbor]:
                came_from[neighbor] = current
                g_score[neighbor] = tentative_g_score
                f_score[neighbor] = g_score[neighbor] + heuristic(neighbor, goal)
                heapq.heappush(open_set, (f_score[neighbor], neighbor))

    return None

Step 4: Defining Path Reconstruction Function

The reconstruct_path() function backtracks from the goal to the start using the came_from dictionary and then reverses the result to obtain the path in start-to-goal order.

Python
def reconstruct_path(came_from, current):
    total_path = [current]
    while current in came_from:
        current = came_from[current]
        total_path.append(current)
    total_path.reverse()
    return total_path

def path_to_edges(path):
    return [(path[i], path[i + 1]) for i in range(len(path) - 1)]

Step 5: Setup Graph and Visualizing the Path

In simple grid-based graph, each node is connected to its neighbors. The graph is represented as a dictionary of nodes where the keys are coordinates and the values are dictionaries of neighbors with their associated edge weights (cost). NetworkX library is used to visualize the graph and highlight the path found by the A* algorithm. The path is visualized by coloring the edges of the graph in red.

Python
graph = {
    (0, 0): {(1, 0): 1, (0, 1): 1},
    (1, 0): {(0, 0): 1, (1, 1): 1, (2, 0): 1},
    (0, 1): {(0, 0): 1, (1, 1): 1},
    (1, 1): {(1, 0): 1, (0, 1): 1, (2, 1): 1},
    (2, 0): {(1, 0): 1, (2, 1): 1},
    (2, 1): {(2, 0): 1, (1, 1): 1, (2, 2): 1},
    (2, 2): {(2, 1): 1}
}

start = (0, 0)
goal = (2, 2)

G = nx.DiGraph()
for node, edges in graph.items():
    for dest, weight in edges.items():
        G.add_edge(node, dest, weight=weight)

path = a_star(graph, start, goal)

pos = {node: (node[1], -node[0]) for node in graph}  
nx.draw(G, pos, with_labels=True, node_color='lightblue', node_size=2000, edge_color='gray', width=2)
nx.draw_networkx_edges(G, pos, edgelist=path_to_edges(path), edge_color='red', width=2)
plt.title('Graph Visualization with A* Path Highlighted')
plt.show()

Output:

download-(2)
Path Solution derived using A* Algorithm
  • Nodes: Represent positions in the grid.
  • Gray edges: Represent available connections.
  • Highlighted edges: Represent the path selected by A*.
  • Start node: (0, 0)
  • Goal node: (2, 2)

The resulting path is:

(0, 0) → (0, 1) → (1, 1) → (2, 1) → (2, 2)

You can download the source code from here.

Advantages

  1. Optimality: When equipped with an admissible heuristic, it is guaranteed to find the shortest path to the goal.
  2. Completeness: It will always find a solution if one exists.
  3. Flexibility: By adjusting heuristics, it can be adapted to a wide range of problem settings and constraints.
  4. Efficiency: With a good heuristic, it explores fewer nodes than uninformed algorithms like Dijkstra’s, making it faster in many cases.

Limitations and Considerations

  1. High Memory Usage: It stores all open and closed nodes which can become impractical for very large graphs.
  2. Heuristic Sensitivity: The efficiency and optimality depend heavily on the quality of the chosen heuristic.
  3. Computational Overhead: In complex or dense graphs, it can still take considerable time to find the path.

Applications

  1. Pathfinding in Games and Robotics: A* is used in the gaming industry to control characters in dynamic environments as well as in robotics for navigating between points.
  2. Network Routing: In telecommunications, it helps in finding the shortest routing path that data packets should take to reach the destination.
  3. Map and Navigation Systems: GPS navigation systems use A* to find optimal driving or walking routes in real time.
  4. Logistics and Supply Chain: A* helps in optimizing routes for delivery vehicles and warehouse robots to minimize travel time and costs.

Algorithm

Greedy Best-First Search

A*

Evaluation Function

f(n)=h(n)

f(n)=g(n)+h(n)

Considers Path Cost?

No

Yes

Uses Heuristic?

Yes

Yes

Optimal?

No

Yes, with appropriate heuristic

Comment

Explore