A simple implementation of the A* algorithm for path-finding on a two-dimensional grid.
Project description
PyAstar2D
This is a very simple C++ implementation of the A* algorithm for pathfinding on a two-dimensional grid. The solver itself is implemented in C++, but is callable from Python. This combines the speed of C++ with the convenience of Python.
I have not done any formal benchmarking, but the solver finds the solution to a 1802 by 1802 maze in 0.29s and a 4008 by 4008 maze in 0.83s when running on my nine-year-old Intel(R) Core(TM) i7-2630QM CPU @ 2.00GHz. See Example Results for more details.
See src/cpp/astar.cpp for the core C++ implementation of the A* shortest
path search algorithm, src/pyastar2d/astar_wrapper.py for the Python wrapper
and examples/example.py for example usage.
When determining legal moves, 4-connectivity is the default, but it is possible
to set allow_diagonal=True for 8-connectivity.
Installation
Instructions for installing pyastar2d are given below.
From PyPI
The easiest way to install pyastar2d is directly from the Python package index:
pip install pyastar2d
From source
You can also install pyastar2d by cloning this repository and building it
yourself. If running on Linux or MacOS, simply run
pip install .
from the root directory. If you are using Windows you may have to install Cython manually first:
pip install Cython
pip install .
To check that everything worked, run the example:
python examples/example.py
As a dependency
Include pyastar2d in your requirements.txt to install from pypi, or add
this line to requirements.txt:
pyastar2d @ git+git://github.com/hjweide/pyastar2d.git@master#egg=pyastar2d
Usage
A simple example is given below:
import numpy as np
import pyastar2d
# The minimum cost must be 1 for the heuristic to be valid.
# The weights array must have np.float32 dtype to be compatible with the C++ code.
weights = np.array([[1, 3, 3, 3, 3],
[2, 1, 3, 3, 3],
[2, 2, 1, 3, 3],
[2, 2, 2, 1, 3],
[2, 2, 2, 2, 1]], dtype=np.float32)
# The start and goal coordinates are in matrix coordinates (i, j).
path = pyastar2d.astar_path(weights, (0, 0), (4, 4), allow_diagonal=True)
print(path)
# The path is returned as a numpy array of (i, j) coordinates.
array([[0, 0],
[1, 1],
[2, 2],
[3, 3],
[4, 4]])
Note that all grid points are represented as (i, j) coordinates. An example
of using pyastar2d to solve a maze is given in examples/maze_solver.py.
Example Results
To test the implementation, I grabbed two nasty mazes from Wikipedia. They are
included in the mazes directory, but are originally from here:
Small and
Large.
I load the .png files as grayscale images, and set the white pixels to 1
(open space) and the black pixels to INF (walls).
To run the examples specify the input and output files using the --input and
--output flags. For example, the following commands will solve the small and
large mazes:
python examples/maze_solver.py --input mazes/maze_small.png --output solns/maze_small.png
python examples/maze_solver.py --input mazes/maze_large.png --output solns/maze_large.png
Small Maze (1802 x 1802):
time python examples/maze_solver.py --input mazes/maze_small.png --output solns/maze_small.png
Loaded maze of shape (1802, 1802) from mazes/maze_small.png
Found path of length 10032 in 0.292794s
Plotting path to solns/maze_small.png
Done
real 0m1.214s
user 0m1.526s
sys 0m0.606s
The solution found for the small maze is shown below:
Large Maze (4002 x 4002):
time python examples/maze_solver.py --input mazes/maze_large.png --output solns/maze_large.png
Loaded maze of shape (4002, 4002) from mazes/maze_large.png
Found path of length 783737 in 0.829181s
Plotting path to solns/maze_large.png
Done
real 0m29.385s
user 0m29.563s
sys 0m0.728s
The solution found for the large maze is shown below:
Motivation
I recently needed an implementation of the A* algorithm in Python to find the
shortest path between two points in a cost matrix representing an image.
Normally I would simply use networkx, but for
graphs with millions of nodes the overhead incurred to construct the graph can
be expensive. Considering that I was only interested in graphs that may be
represented as two-dimensional grids, I decided to implement it myself using
this special structure of the graph to make various optimizations.
Specifically, the graph is represented as a one-dimensional array because there
is no need to store the neighbors. Additionally, the lookup tables for
previously-explored nodes (their costs and paths) are also stored as
one-dimensional arrays. The implication of this is that checking the lookup
table can be done in O(1), at the cost of using O(n) memory. Alternatively, we
could store only the nodes we traverse in a hash table to reduce the memory
usage. Empirically I found that replacing the one-dimensional array with a
hash table (std::unordered_map) was about five times slower.
Tests
The default installation does not include the dependencies necessary to run the tests. To install these, first run
pip install -r requirements-dev.txt
before running
pytest
The tests are fairly basic but cover some of the more common pitfalls. Pull requests for more extensive tests are welcome.
Code Formatting
It's recommended that you use pre-commit to ensure linting procedures are
run on any code you write. See pre-commit.com for
more information.
Reference pre-commit's installation instructions
for software installation on your OS/platform. After you have the software
installed, run pre-commit install on the command line. Now every time you commit
to this project's code base the linter procedures will automatically run over the
changed files. To run pre-commit on files preemtively from the command line use:
pip install -r requirements-dev.txt
pre-commit run --all-files
The code base has been formatted by Black.
Furthermore, try to conform to PEP8. You should set up your preferred editor to
use flake8 as its Python linter, but pre-commit will ensure compliance before a
git commit is completed. This will use the flake8 configuration within
.flake8, which ignores several errors and stylistic considerations.
References
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 Distributions
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 pyastar2d-1.1.3.tar.gz.
File metadata
- Download URL: pyastar2d-1.1.3.tar.gz
- Upload date:
- Size: 4.6 MB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
7f29f09fcb354a871632410b827e8bbc4ebf3fbf79e88877bac61635ac2ad394
|
|
| MD5 |
8945890e72c661cd0e9f95307aa8c8a1
|
|
| BLAKE2b-256 |
ddcb29a5676326019921b5f6a76cbc4d21c944070d2e3666c77174da3c3920bb
|
File details
Details for the file pyastar2d-1.1.3-cp39-abi3-win_amd64.whl.
File metadata
- Download URL: pyastar2d-1.1.3-cp39-abi3-win_amd64.whl
- Upload date:
- Size: 15.4 kB
- Tags: CPython 3.9+, Windows x86-64
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
4595594c42992462c94dc7f671f039452abc06d01db716bfb7db943c234746ff
|
|
| MD5 |
ca35117ea83ff4a156e27127895d30ec
|
|
| BLAKE2b-256 |
11bf8e649521329a386c58f36a4f15369c38b7ce0c071cb3df66a96ee9b3f238
|
File details
Details for the file pyastar2d-1.1.3-cp39-abi3-win32.whl.
File metadata
- Download URL: pyastar2d-1.1.3-cp39-abi3-win32.whl
- Upload date:
- Size: 14.8 kB
- Tags: CPython 3.9+, Windows x86
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
c9b0200f2fedd468bf8003a0f16202f082e374fb518965961a75219c264d5828
|
|
| MD5 |
27f51cb9f85e472a08f582f68a389987
|
|
| BLAKE2b-256 |
74c7a6205151c203faad72ceb1a6724bbbcdfc997e9fc7043a3bacb41fc0ebd1
|
File details
Details for the file pyastar2d-1.1.3-cp39-abi3-musllinux_1_2_x86_64.whl.
File metadata
- Download URL: pyastar2d-1.1.3-cp39-abi3-musllinux_1_2_x86_64.whl
- Upload date:
- Size: 1.1 MB
- Tags: CPython 3.9+, musllinux: musl 1.2+ x86-64
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
4193b62dbbb9264e1aedc2476bcd75563737b80bb12d383ad4145f0275d930e7
|
|
| MD5 |
78ca799f7042bdb4c82c3f95c6393b0d
|
|
| BLAKE2b-256 |
a501b2e84368e48eb3c8dd8624510199dcde010796ade3fbf86b81dbc30d5814
|
File details
Details for the file pyastar2d-1.1.3-cp39-abi3-musllinux_1_2_aarch64.whl.
File metadata
- Download URL: pyastar2d-1.1.3-cp39-abi3-musllinux_1_2_aarch64.whl
- Upload date:
- Size: 1.0 MB
- Tags: CPython 3.9+, musllinux: musl 1.2+ ARM64
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
49a3c3cb79b4ebc7ec952eef2c39022c22542d51f700136aa01f0d2257a00402
|
|
| MD5 |
f10f89342a3ef904644782948ba52631
|
|
| BLAKE2b-256 |
2bd4ee1644dc3e8d491823e9bc2b6bec723c9089716eadf6f0fb014434840ab4
|
File details
Details for the file pyastar2d-1.1.3-cp39-abi3-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl.
File metadata
- Download URL: pyastar2d-1.1.3-cp39-abi3-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl
- Upload date:
- Size: 56.8 kB
- Tags: CPython 3.9+, manylinux: glibc 2.24+ x86-64, manylinux: glibc 2.28+ x86-64
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
ea76687d79132f102f57770e7fff61988ffff2a9f6e4d0795e65acc6ceb4dc61
|
|
| MD5 |
bd59be8efeb390f37dd421f99693db79
|
|
| BLAKE2b-256 |
e52c40b0c23cc5cb7c418e075db4b3dc57c82552caf8ecc4146ff2be771483b9
|
File details
Details for the file pyastar2d-1.1.3-cp39-abi3-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl.
File metadata
- Download URL: pyastar2d-1.1.3-cp39-abi3-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl
- Upload date:
- Size: 56.8 kB
- Tags: CPython 3.9+, manylinux: glibc 2.24+ ARM64, manylinux: glibc 2.28+ ARM64
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
16a9213e512cf802133791cc80586f171b20e442e2e2792faafcb86356395a35
|
|
| MD5 |
33daf80239d1e2079caef3e01d8b3b09
|
|
| BLAKE2b-256 |
eb771ab0995c4413c68f220998499bef48cc6c745af7ee60e2f66eade188f5df
|
File details
Details for the file pyastar2d-1.1.3-cp39-abi3-macosx_11_0_arm64.whl.
File metadata
- Download URL: pyastar2d-1.1.3-cp39-abi3-macosx_11_0_arm64.whl
- Upload date:
- Size: 12.7 kB
- Tags: CPython 3.9+, macOS 11.0+ ARM64
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
cd5b84426cfd14621f3a3113b5ee715e5e3324e128522b827cad0b7ba8a636c3
|
|
| MD5 |
ce1afe981900832ae9f410127d88def7
|
|
| BLAKE2b-256 |
004cb0860991bd2bc132114a975fb891b1d138432b68a359a262b472949dbdcb
|
File details
Details for the file pyastar2d-1.1.3-cp39-abi3-macosx_10_9_x86_64.whl.
File metadata
- Download URL: pyastar2d-1.1.3-cp39-abi3-macosx_10_9_x86_64.whl
- Upload date:
- Size: 12.2 kB
- Tags: CPython 3.9+, macOS 10.9+ x86-64
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
4c94a454e99757aea4863fa4272e635962c1376411a9623f9afdccab9fa09eb5
|
|
| MD5 |
b4f74f7e2d37703781be7236899faca4
|
|
| BLAKE2b-256 |
92b95758ad23c8a3890e7d47f4afbf29dc92386a365e8dc5176107854ad48efd
|