Subroutine Logo
Subroutine
← Back to Playground Algorithms Intermediate

Dijkstra's & A* Pathfinding: Heuristics & Graph Traversal

An interactive exploration of graph search algorithms, comparing Dijkstra's uniform cost search against A* heuristic estimation.

Published: 2026-07-26
#Algorithms#Pathfinding#A*#Dijkstra#Graphs

Pathfinding is central to computer science—powering GPS navigation systems, network packet routing, and video game AI. While Dijkstra’s algorithm guarantees finding the shortest path by exploring all directions uniformly, the A Search algorithm* uses a heuristic function to steer exploration directly toward the destination.


1. Summary & Key Takeaways

  • Dijkstra’s Algorithm: Evaluates nodes based strictly on path cost from the start: f(n)=g(n)f(n) = g(n)
  • AA^* Search Algorithm: Adds an admissible heuristic h(n)h(n) estimating remaining distance to the goal: f(n)=g(n)+h(n)f(n) = g(n) + h(n)
  • Manhattan Distance Heuristic: For grid graphs with 4-directional movement: h(n)=x1x2+y1y2h(n) = |x_1 - x_2| + |y_1 - y_2|
  • Efficiency Boost: AA^* evaluates significantly fewer nodes than Dijkstra while still guaranteeing the shortest optimal path if the heuristic never overestimates the true cost (h(n)h(n)h(n) \le h^*(n)).

2. Interactive Pathfinding Playground

Use the interactive 2D grid below to place wall barriers. Switch between AA^* Search and Dijkstra to observe how heuristic guidance drastically reduces the number of visited nodes!

Interactive Experiment

Click on grid cells to toggle wall barriers, then click Run A* Search versus Run Dijkstra. Notice how AA^* steers toward the target (T) instantly!

Dijkstra's Algorithm & A* SearchGraph Pathfinding

Compare greedy uniform-cost traversal (Dijkstra) against heuristic-guided search (A* Manhattan).

Nodes Visited: 0
Path Length: 0
Pathfinding Implementation Code
pathfinding.py
Python
# Dijkstra & A* Search Pathfinding in Python
import heapq

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

def a_star_search(start, goal, grid):
    open_set = []
    heapq.heappush(open_set, (0, start))
    came_from = {}
    g_score = {start: 0}
    
    while open_set:
        current = heapq.heappop(open_set)[1]
        if current == goal:
            return reconstruct_path(came_from, current)
        
        for neighbor in get_neighbors(current, grid):
            tentative_g = g_score[current] + 1
            if tentative_g < g_score.get(neighbor, float('inf')):
                came_from[neighbor] = current
                g_score[neighbor] = tentative_g
                f_score = tentative_g + heuristic(neighbor, goal)
                heapq.heappush(open_set, (f_score, neighbor))

3. Mathematical Foundations

The core score f(n)f(n) assigned to each node during priority queue exploration determines traversal order:

1. Dijkstra (f(n)=g(n)f(n) = g(n))

Explores nodes in concentric circles outward from the origin regardless of target location.

2. AA^* (f(n)=g(n)+h(n)f(n) = g(n) + h(n))

Directs exploration toward the goal. For 4-way grid movement, Manhattan distance provides an admissible, consistent heuristic:

h(n)=xcurrentxtarget+ycurrentytargeth(n) = |x_{\text{current}} - x_{\text{target}}| + |y_{\text{current}} - y_{\text{target}}|


4. Algorithm Comparison Matrix

AlgorithmEvaluation FunctionHeuristic Needed?Explored NodesGuarantees Shortest Path?
Dijkstraf(n)=g(n)f(n) = g(n)NoHigh (Uniform Radiating Search)Yes
AA^* Searchf(n)=g(n)+h(n)f(n) = g(n) + h(n)Yes (Admissible hh)Low (Directed Heuristic Search)Yes
Greedy Best-Firstf(n)=h(n)f(n) = h(n)YesMinimal (Ignores past cost gg)No