Skip to article frontmatterSkip to article content
Site not loading correctly?

This may be due to an incorrect BASE_URL configuration. See the MyST Documentation for reference.

Path Finder Visualizer

Interactive exploration of graph search and maze generation

The previous notebooks taught the logic behind BFS, DFS, Dijkstra, cycle detection, and topological ordering. This notebook shifts from static diagrams to interactive route exploration. Instead of only reading an algorithm trace, you can watch a path-finding strategy expand across a grid and compare how different search rules change the route and the amount of exploration.

Why this matters in practice
  • route planners compare alternatives before choosing a path through a road or warehouse network

  • robotics systems often care about both target direction and obstacle avoidance

  • product teams use search visualizations to explain why one strategy is more efficient than another

Worked Exploration and Guided Practice

Expected output
Shortest path in this sample: BFS 10
Fewest visited cells in this sample: Greedy Best First 9

This contrast is the main lesson of the visualizer: an algorithm can look fast because it explores fewer cells, but that does not automatically mean it found the best path.

Why include this?

A* and greedy best-first search often use a heuristic like Manhattan distance to estimate how close a cell is to the goal. The visualizer makes that goal-directed behavior visible even when the exact score is hidden from the interface.

Suggested Exploration

  1. Run BFS on the default grid and watch how evenly the frontier grows from the start.

  2. Switch to DFS on the same grid and compare how quickly it commits to one direction.

  3. Run A* and compare both the final path and the number of visited cells against BFS.

  4. Generate a maze, keep the same start and end nodes, and compare BFS, DFS, A*, and Greedy Best First one by one.

  5. Move the start and goal nodes after one run and predict which algorithm will change behavior the most visibly.

Guided Practice

Which algorithm in the visualizer guarantees the shortest path in an unweighted grid?

DFS onlyDFS can find a path, but it does not guarantee the shortest one.
BFS, and typically A* when using an admissible heuristicCorrect. BFS guarantees the shortest unweighted path, and A* is designed to preserve optimality under the right heuristic conditions.
Greedy Best First onlyGreedy search may be quick, but it does not guarantee the best path.
Every algorithm shownThe visualizer is useful precisely because the algorithms behave differently.

What does it usually mean if an algorithm visits fewer cells but returns a longer path?

It is definitely better because it was fasterFewer visits can help efficiency, but a longer path may be a worse result.
It explored more selectively, but did not optimize for the best routeCorrect. This is a common tradeoff shown by greedy or depth-first behavior.
The maze must be invalidDifferent algorithms can behave differently on a valid maze.
The start node moved automaticallyThat is not the general explanation.

Why is the visualizer a good review tool after the graph-search notebooks?

Because it replaces all code examples from the earlier notebooksIt complements the earlier notebooks; it does not replace them.
Because it makes frontier expansion, backtracking, and goal-directed search visibleCorrect. The animation turns abstract search rules into observable behavior.
Because it adds Dijkstra mode to the bookThis visualizer does not include a Dijkstra mode.
Because every run always produces the same pathDifferent mazes and algorithms lead to different outcomes.

Exercises

  1. On one maze, record the path length and visited-cell count for BFS, DFS, A*, and Greedy Best First. Which algorithm gives the best tradeoff for that maze?

  2. Create a maze where DFS looks efficient at first but eventually gives a noticeably longer route than BFS.

  3. Change the start and goal positions and explain whether the heuristic-based algorithms become more or less convincing.

Hint

Hold the maze constant when comparing algorithms. Otherwise, you cannot tell whether the difference came from the search rule or from the obstacle layout itself.

Key Takeaway

The path finder visualizer makes graph-search behavior observable: BFS spreads by layers, DFS dives deeply, and heuristic-based methods aim toward the goal more aggressively. Use it to compare path quality against exploration cost. The next stop in the sequence is the DSA_tests.ipynb assessment notebook, where these graph ideas join the broader data-structures-and-algorithms review.

Core Idea and Visual Intuition

A path-finding visualizer turns graph search into motion. Each grid cell behaves like a node, each allowed move behaves like an edge, and each algorithm chooses a different rule for which frontier cell to explore next.

BFS
DFS
A*
Greedy Best First

Explores outward layer by layer. In an unweighted grid, it guarantees the shortest path by number of steps, but it may visit many cells.

Embedded Visualizer

If the embedded view feels cramped, open the path finder visualizer in a new tab. You can also start from the algo-visualizers home page.

How to read the animation
  • visited cells show where the algorithm explored while searching

  • the highlighted final route is the path selected once the goal is reached

  • a shorter final path is not the only metric; the number of visited cells also affects efficiency

  • comparing two algorithms on the same maze is more informative than changing both the maze and the algorithm at once

sample_runs = [
    {"algorithm": "BFS", "path_length": 10, "visited_cells": 24, "guarantees_shortest_unweighted_path": True},
    {"algorithm": "DFS", "path_length": 14, "visited_cells": 16, "guarantees_shortest_unweighted_path": False},
    {"algorithm": "A*", "path_length": 10, "visited_cells": 13, "guarantees_shortest_unweighted_path": True},
    {"algorithm": "Greedy Best First", "path_length": 11, "visited_cells": 9, "guarantees_shortest_unweighted_path": False},
]

print("Algorithm comparison from one sample maze:\n")
for run in sample_runs:
    print(
        f"{run['algorithm']}: path length = {run['path_length']}, "
        f"visited cells = {run['visited_cells']}, "
        f"shortest-path guarantee = {run['guarantees_shortest_unweighted_path']}"
    )

best_shortest = min(
    (run for run in sample_runs if run["guarantees_shortest_unweighted_path"]),
    key=lambda run: (run["path_length"], run["visited_cells"]),
)

print("\nMost efficient shortest-path run in this sample:", best_shortest["algorithm"])
Algorithm comparison from one sample maze:

BFS: path length = 10, visited cells = 24, shortest-path guarantee = True
DFS: path length = 14, visited cells = 16, shortest-path guarantee = False
A*: path length = 10, visited cells = 13, shortest-path guarantee = True
Greedy Best First: path length = 11, visited cells = 9, shortest-path guarantee = False

Most efficient shortest-path run in this sample: A*