Skip to main content

search-library

CI PyPI Python 3.11+ License: MIT Ruff MyPy Coverage

An extensible search algorithm framework for discrete spaces. Designed as both a production-ready library and an academic reference implementation for graph search algorithms in artificial intelligence.

Motivation

Search algorithms are fundamental to artificial intelligence and computer science. From pathfinding in video games to route planning in logistics, from puzzle solving to knowledge graph traversal, the ability to efficiently explore state spaces is a core capability.

This library was built to:

  • Provide correct, well-tested implementations of classical search algorithms
  • Serve as a reference for students and researchers studying AI search
  • Offer a unified API that enables fair comparison between algorithms
  • Demonstrate software engineering best practices in algorithm library design

Algorithms

Algorithm Strategy Optimal Complete Time Space
A* Best-first (f = g + h) Yes (admissible h) Yes O(b^d) O(b^d)
BFS Level-order (FIFO) Yes (unweighted) Yes O(V + E) O(V)
DFS Depth-first (LIFO) No Yes (finite) O(V + E) O(bm)
Dijkstra Best-first (g only) Yes Yes O((V+E) log V) O(V)
Bidirectional Dual BFS Yes (unweighted) Yes O(b^(d/2)) O(b^(d/2))

Where: b = branching factor, d = solution depth, m = max depth, V = vertices, E = edges.

A* Search

Informed search using f(n) = g(n) + h(n). Guarantees optimal paths when the heuristic is admissible (never overestimates). The most efficient algorithm when a good heuristic is available.

Breadth-First Search (BFS)

Explores nodes level by level. Guarantees the shortest path by edge count in unweighted graphs. Ideal when all transitions have equal cost.

Depth-First Search (DFS)

Explores as deep as possible before backtracking. Uses minimal memory but does not guarantee optimal paths. Useful for existence checks and exhaustive exploration.

Dijkstra's Algorithm

Equivalent to A* with h(n) = 0. Finds the minimum-cost path in weighted graphs without requiring a heuristic. The baseline optimal algorithm for weighted search.

Bidirectional Search

Searches simultaneously from start and goal, meeting in the middle. Reduces the effective branching factor exponentially, making it ideal for large unweighted graphs.

Architecture

src/search_library/
├── core/               # Base abstractions
│   ├── types.py        # TypeVar T bound to Hashable
│   ├── nodes.py        # Node dataclass (state, g_cost, h_cost, f_cost)
│   ├── problem.py      # SearchProblem ABC (initial_state, is_goal, successors, heuristic)
│   └── result.py       # SearchResult (path, total_cost, nodes_explored, success)
├── algorithms/         # Search implementations
│   ├── base.py         # SearchAlgorithm ABC (unified interface)
│   ├── astar.py        # A* Search
│   ├── bfs.py          # Breadth-First Search
│   ├── dfs.py          # Depth-First Search
│   ├── dijkstra.py     # Dijkstra's Algorithm
│   └── bidirectional.py # Bidirectional BFS
├── heuristics/         # Pluggable heuristic functions
│   ├── base.py         # Heuristic ABC (Strategy Pattern)
│   ├── manhattan.py    # Manhattan distance (L1)
│   └── euclidean.py    # Euclidean distance (L2)
├── graph/              # Weighted graph data structure
│   ├── graph.py        # Graph + GraphSearchProblem adapter
│   └── edges.py        # Edge dataclass
├── grid/               # 2D grid for pathfinding
│   ├── grid.py         # Grid with obstacles, 4/8-directional movement
│   └── grid_search.py  # GridSearchProblem adapter
├── utils/              # Visualization and formatting
└── exceptions/         # Custom error hierarchy

Design Principles

  • SearchProblem defines the problem space (initial state, goal test, successors, heuristic)
  • SearchAlgorithm is the unified interface all algorithms implement
  • Adapter Pattern converts Graph/Grid into SearchProblem transparently
  • Strategy Pattern makes heuristics interchangeable at runtime
  • SOLID principles ensure each component has a single responsibility

Installation

pip install search-library

Or with uv:

uv add search-library

Usage

A* on a Weighted Graph

from search_library import Graph, AStarSearch

# Build a weighted undirected graph
graph = Graph[str](directed=False)
graph.add_edge("A", "B", 4.0)
graph.add_edge("B", "C", 2.0)
graph.add_edge("A", "C", 7.0)
graph.add_edge("C", "D", 1.0)

# Solve with A*
problem = graph.to_search_problem("A", "D")
result = AStarSearch(problem).search()

print(result.path)           # ['A', 'B', 'C', 'D']
print(result.total_cost)     # 7.0
print(result.nodes_explored) # 4

A* on a 2D Grid (Pathfinding)

from search_library import Grid, AStarSearch, ManhattanHeuristic
from search_library.grid import GridSearchProblem

# 0 = walkable, 1 = obstacle
maze = [
    [0, 0, 0, 0, 0],
    [0, 1, 1, 1, 0],
    [0, 0, 0, 1, 0],
    [0, 1, 0, 0, 0],
    [0, 0, 0, 0, 0],
]

grid = Grid.from_matrix(maze)
problem = GridSearchProblem(grid, start=(0, 0), goal=(4, 4))
result = AStarSearch(problem).search()

print(result.success)    # True
print(result.total_cost) # 8.0
print(result.steps)      # 8

Comparing Algorithms

from search_library import Graph, AStarSearch, BFS, Dijkstra

graph = Graph[str](directed=False)
graph.add_edge("S", "A", 1.0)
graph.add_edge("S", "B", 4.0)
graph.add_edge("A", "B", 2.0)
graph.add_edge("B", "G", 1.0)

problem = graph.to_search_problem("S", "G")

for Algorithm in [AStarSearch, BFS, Dijkstra]:
    result = Algorithm(problem).search()
    print(f"{Algorithm.__name__:20} | cost={result.total_cost:.1f} | explored={result.nodes_explored}")

Convenience Functions

from search_library import astar_search, bfs_search, dfs_search, dijkstra_search

result = astar_search(problem)
result = bfs_search(problem, max_iterations=10000)
result = dijkstra_search(problem, strict=True)
result = dfs_search(problem, track_explored=True)

Grid Visualization

from search_library.utils import print_grid

grid = Grid.from_matrix(maze)
problem = GridSearchProblem(grid, (0, 0), (4, 4))
result = AStarSearch(problem).search(track_explored=True)

print_grid(grid, result, show_explored=True)
# S * * # .
# . # * # .
# . . * # .
# . # * * *
# . . . . G

Academic Use Cases

  • Pathfinding: Optimal route computation in maps, games, and robotics
  • Puzzle solving: N-puzzle, Rubik's cube via state-space search
  • Knowledge graphs: Shortest path between concepts in semantic networks
  • Algorithm comparison: Empirical analysis of search strategies (optimality, completeness, efficiency)
  • AI education: Teaching informed vs. uninformed search with clean, readable code
  • Research prototyping: Quick experimentation with custom search problems and heuristics

Complexity Analysis

Algorithm Time (worst) Space (worst) Optimal Notes
A* O(b^d) O(b^d) Yes* *With admissible heuristic
BFS O(V + E) O(V) Yes** **For uniform-cost edges
DFS O(V + E) O(bm) No m = maximum depth
Dijkstra O((V+E) log V) O(V) Yes Non-negative weights required
Bidirectional O(b^(d/2)) O(b^(d/2)) Yes** **Unweighted / symmetric

Development

# Clone and install
git clone https://github.com/ahincho/search-library.git
cd search-library
uv sync

# Run tests (147 tests, 96%+ coverage)
uv run pytest

# Lint and type-check
uv run ruff check src/ tests/
uv run mypy src/

# Build
uv build

Future Work

  • Additional heuristics (Chebyshev, Octile, domain-specific)
  • Iterative Deepening A* (IDA*)
  • Weighted A* and anytime search
  • Performance benchmarking suite
  • Interactive visualization (matplotlib / terminal)
  • Parallel search for large state spaces

References

  • Hart, P. E., Nilsson, N. J., & Raphael, B. (1968). A Formal Basis for the Heuristic Determination of Minimum Cost Paths. IEEE Transactions on Systems Science and Cybernetics.
  • Russell, S., & Norvig, P. (2020). Artificial Intelligence: A Modern Approach (4th ed.). Pearson.
  • Cormen, T. H., et al. (2022). Introduction to Algorithms (4th ed.). MIT Press.

License

MIT — Free for academic and commercial use.

Author

Developed by ahincho at Universidad Nacional de San Agustin (UNSA).

Metadata

Release files for search-library 1.0.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for search-library 1.0.0
File Size Uploaded
search_library-1.0.0.tar.gz 27.9 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for search-library 1.0.0
File Interpreter ABI Platform
search_library-1.0.0-py3-none-any.whl Python 3 none any Details

Total release size: 59.4 kB

Release files / search_library-1.0.0.tar.gz

Download URL search_library-1.0.0.tar.gz
Size 27.9 kB
Tags Source
SHA-256 checksum
How to use checksums
f4c9975a9b53e5ab6677e52a59b23bdf495ccf6d8b5c9042366af87cbc27d2b6
BLAKE2b-256 checksum
How to use checksums
c5a103cca7eeb840dcb4d551fafefc83c84a8b27e34984e3da6e0f57fdd4e9c8
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.1.0 CPython/3.13.12

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Jun 21, 2026.

Transparency log

Release files / search_library-1.0.0-py3-none-any.whl

Download URL search_library-1.0.0-py3-none-any.whl
Size 31.5 kB
Tags Python 3
SHA-256 checksum
How to use checksums
7074be27e6ec982e14cee8de69b4b948b451287c5276747ad79ea3ea83cb4e54
BLAKE2b-256 checksum
How to use checksums
bf338df70599b22e9b0d683b0ae5541786de79c193d4b88188bc32195468d5b8
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.1.0 CPython/3.13.12

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Jun 21, 2026.

Transparency log

Release history Release notifications | RSS feed

This release

1.0.0 This release

2 release files

0.2.0

2 release files

0.1.0

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page