Skip to main content

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

CI PyPI Python License: MIT

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


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

pathos_ai-0.1.0.tar.gz (85.1 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

pathos_ai-0.1.0-py3-none-any.whl (32.9 kB view details)

Uploaded Python 3

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

Hashes for pathos_ai-0.1.0.tar.gz
Algorithm Hash digest
SHA256 0d0461c0478825ef7ef75d84400343717f502a292be681cae6ac8127721890a7
MD5 6ff70f2c6111ff8dad9d71196fa4ad75
BLAKE2b-256 416422af2c422ad845693d8b7b35393a1f81a2f425439161223e115991f20965

See more details on using hashes here.

Provenance

The following attestation bundles were made for pathos_ai-0.1.0.tar.gz:

Publisher: publish.yaml on gia-uh/pathos

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

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

Hashes for pathos_ai-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 6d0fdd2243f4a45e414e9ec5cc925e83be0159f9f4d88e5dcef4dc1d358374b0
MD5 cc28b88f83d5fd51fb631f09ed17bb79
BLAKE2b-256 db798f8b5a87fc0ba430e69316e74817d1a4163a3c5702af676c751894eb0444

See more details on using hashes here.

Provenance

The following attestation bundles were made for pathos_ai-0.1.0-py3-none-any.whl:

Publisher: publish.yaml on gia-uh/pathos

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page