Production-ready classical AI search algorithms — declare your problem, the solver picks the algorithm. Includes an anytime A* cascade by default.
Project description
PATHOS — Python AI Search Library
Production-ready classical AI search algorithms for Python. No machine learning. Pure search.
Documentation · PyPI · Examples
Philosophy
Define your problem, not your algorithm. PATHOS inspects the capabilities you declare and selects the best algorithm automatically.
from pathos import Space
space = Space().initial("Madrid")
@space.successors
def neighbors(city):
for next_city, km in roads[city]:
yield next_city, next_city
@space.goal
def reached(city): return city == "Lisboa"
@space.heuristic
def h(city): return straight_line_km(city, "Lisboa")
result = space.solver().solve()
# → Uses A* automatically (has successors + goal + heuristic)
print(result.path, result.cost, result.algorithm)
Install
pip install pathos-ai
Algorithm Families
| Declare | Algorithms Available |
|---|---|
@evaluate |
Simulated Annealing, Genetic Algorithm, DE, PSO |
@successors + @goal |
BFS, DFS, IDDFS (DFS is non-optimal — for shortest paths prefer BFS/UCS) |
@successors + @evaluate |
Hill Climbing, Tabu Search |
@successors + @goal + @heuristic |
A*, IDA*, Greedy Best-First |
@successors + @goal + @heuristic + @evaluate |
Weighted A*, UCS |
.adversarial() + @terminal + @utility |
Minimax, Alpha-Beta, MCTS |
CSPSpace + @constraint |
Backtracking, Forward Checking |
Specialized Spaces
from pathos import GraphSpace, CSPSpace, TourSpace, GameSpace
# Graph search (auto-provides successors from adjacency)
space = GraphSpace(graph=city_graph).initial("A")
# Constraint satisfaction (auto-provides successors + goal)
csp = CSPSpace(variables=["X", "Y", "Z"])
# Tour optimization (TSP — auto-provides 2-opt neighborhood)
tour = TourSpace(nodes=cities, distances=dist_matrix)
# Adversarial games (auto-sets adversarial mode)
game = GameSpace().initial(board)
Modes — exact, approximate, auto
The solver() factory selects an algorithm based on the space's declared
capabilities and the mode you ask for. Three modes:
# Default: anytime cascade. Always-ready, gives best incumbent under
# the budget (1h if you don't set one). Optimal if it finishes.
space.solver().solve()
space.solver(timeout=60).solve()
# Single-shot admissible algorithm. No timeout default; runs to
# completion or until you cut it off.
space.solver(mode="exact").solve()
# Single-shot bounded-suboptimal algorithm. Faster than exact.
space.solver(mode="approximate").solve()
Under mode="auto" (default), AnytimeAStar wins selection on A*-family
spaces and runs a cascade [Greedy, WAStar(5,3,2,1.5), AStar], keeping
the best incumbent across phases. On a generous budget the final A* phase
returns the proven-optimal answer; on a tight budget you get the best
incumbent so far instead of not_found.
SearchResult.epsilon tells you the quality bound: 1.0 is proven
optimal, >1.0 is ε-bounded (cost ≤ ε × optimal), inf is unbounded
(greedy), None means the algorithm doesn't report a bound (e.g.
metaheuristics).
result = space.solver(timeout=10).solve()
if result.optimal:
print(f"Optimal: cost {result.cost}")
else:
print(f"ε-bounded ({result.epsilon}): cost {result.cost}")
Every metaheuristic is naturally anytime regardless of mode — set a
timeout and the algorithm returns its best individual seen so far
when the budget runs out (cooperative CancelToken protocol).
Parallel Evaluation
Population-based algorithms (GA, DE, LocalBeamSearch) support multiprocessing via .parallel(n):
# Evaluate all candidates in parallel across 4 processes
space = Space().initial(lambda: random_genome()).parallel(4)
# evaluate fn must be a module-level function (picklable)
def fitness(genome): return -sum(genome)
space.evaluate(fitness)
result = GeneticAlgorithm(space, pop_size=200, generations=500).solve()
Pass n=1 (default) for serial execution. Falls back automatically when population size is 1.
Direct Algorithm Access
from pathos.algorithms import AStar, GeneticAlgorithm, AlphaBeta
result = AStar(space).solve() # bypass auto-selection
SearchResult
Every algorithm returns a uniform SearchResult:
result.solution # final state
result.path # list of (action, state) steps
result.cost # total cost
result.algorithm # algorithm name
result.nodes_expanded
result.elapsed # seconds
result.found # bool
Performance
Reference numbers from python -m benchmarks.bench --repeat 3 on an Intel
i7-6820HQ @ 2.70 GHz, Python 3.13. Algorithms are the ones auto-selected by
space.solver(). Reproduce with the same command; raw records dumped via
--json.
N-Queens (Backtracking, CSPSpace)
| N | elapsed (s, median) | nodes expanded |
|---|---|---|
| 6 | 0.0003 | 31 |
| 8 | 0.0022 | 113 |
| 10 | 0.0031 | 102 |
| 12 | 0.0149 | 261 |
| 14 | 0.1726 | 1 899 |
| 16 | 1.2363 | 10 052 |
TSP (TabuSearch, TourSpace, 100 iters)
| cities | elapsed (s, median) | tour cost (median) |
|---|---|---|
| 5 | 0.0014 | 197.8 |
| 8 | 0.0060 | 253.3 |
| 12 | 0.0224 | 272.2 |
| 16 | 0.0439 | 354.9 |
| 20 | 0.0800 | 383.4 |
| 25 | 0.1593 | 409.3 |
8-Puzzle (A* + Manhattan)
| scramble depth | elapsed (s, median) | nodes expanded | solution length |
|---|---|---|---|
| 10 | 0.0001 | 12 | 10 |
| 20 | 0.0042 | 461 | 20 |
| 30 | 0.0097 | 1 397 | 24 |
| 40 | 0.0127 | 1 728 | 26 |
| 50 | 0.0086 | 1 186 | 22 |
Solution length plateaus around 22–26 because the 8-puzzle state-space diameter is ~31 — deeper scrambles don't make harder instances.
Examples
License
MIT — gia-uh
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file pathos_ai-0.1.0.tar.gz.
File metadata
- Download URL: pathos_ai-0.1.0.tar.gz
- Upload date:
- Size: 85.1 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
0d0461c0478825ef7ef75d84400343717f502a292be681cae6ac8127721890a7
|
|
| MD5 |
6ff70f2c6111ff8dad9d71196fa4ad75
|
|
| BLAKE2b-256 |
416422af2c422ad845693d8b7b35393a1f81a2f425439161223e115991f20965
|
Provenance
The following attestation bundles were made for pathos_ai-0.1.0.tar.gz:
Publisher:
publish.yaml on gia-uh/pathos
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
pathos_ai-0.1.0.tar.gz -
Subject digest:
0d0461c0478825ef7ef75d84400343717f502a292be681cae6ac8127721890a7 - Sigstore transparency entry: 1705297313
- Sigstore integration time:
-
Permalink:
gia-uh/pathos@685bbb2723a2a7f4b1b03f131eb7794b1894ddd1 -
Branch / Tag:
refs/tags/v0.1.0 - Owner: https://github.com/gia-uh
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yaml@685bbb2723a2a7f4b1b03f131eb7794b1894ddd1 -
Trigger Event:
release
-
Statement type:
File details
Details for the file pathos_ai-0.1.0-py3-none-any.whl.
File metadata
- Download URL: pathos_ai-0.1.0-py3-none-any.whl
- Upload date:
- Size: 32.9 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
6d0fdd2243f4a45e414e9ec5cc925e83be0159f9f4d88e5dcef4dc1d358374b0
|
|
| MD5 |
cc28b88f83d5fd51fb631f09ed17bb79
|
|
| BLAKE2b-256 |
db798f8b5a87fc0ba430e69316e74817d1a4163a3c5702af676c751894eb0444
|
Provenance
The following attestation bundles were made for pathos_ai-0.1.0-py3-none-any.whl:
Publisher:
publish.yaml on gia-uh/pathos
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
pathos_ai-0.1.0-py3-none-any.whl -
Subject digest:
6d0fdd2243f4a45e414e9ec5cc925e83be0159f9f4d88e5dcef4dc1d358374b0 - Sigstore transparency entry: 1705297391
- Sigstore integration time:
-
Permalink:
gia-uh/pathos@685bbb2723a2a7f4b1b03f131eb7794b1894ddd1 -
Branch / Tag:
refs/tags/v0.1.0 - Owner: https://github.com/gia-uh
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yaml@685bbb2723a2a7f4b1b03f131eb7794b1894ddd1 -
Trigger Event:
release
-
Statement type: