Skip to content

Commit

Permalink
Merge pull request #6 from harisankar95/code-restructuring
Browse files Browse the repository at this point in the history
Code restructuring
  • Loading branch information
harisankar95 authored Jan 21, 2024
2 parents 8588618 + 97806e7 commit 348c06a
Show file tree
Hide file tree
Showing 17 changed files with 798 additions and 302 deletions.
67 changes: 48 additions & 19 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,42 +5,71 @@ feature developments, extensions, or bugfixes that you are working on.
An easy way is to open an issue or a pull request in which you explain
what you are trying to do.

Before starting your work, please check the existing issues and discussions to avoid duplicate efforts. Engaging in discussions on issues can provide better clarity and enhance community interaction.

## Pull Requests

The preferred way to contribute to *pathfinding3D* is to fork the main repository on Github, then submit a "pull request"
(PR):
The preferred way to contribute to *pathfinding3D* is to fork the main repository on Github, then submit a "pull request" (PR). Follow this checklist before submitting your PR:

1. Fork the [project repository](https://github.com/harisankar95/pathfinding3D):
click on the 'Fork' button near the top of the page. This creates a copy of
the code under your account on the Github server.
click on the ``Fork`` button near the top of the page. This creates a copy of
the code under your namespace on the Github servers.

2. Clone this repository to your local disk:

```bash
git clone [email protected]:YourLogin/pathfinding3D.git
cd pathfinding3D
```

3. Prepare the development environment:

2. Clone this copy to your local disk:
```bash
pip install numpy pytest sphinx
```

git clone [email protected]:YourLogin/pathfinding3D.git
4. Create a new branch to hold your changes, for example (replace
``my-feature`` with a short but descriptive name of your feature, bugfix, etc.):

3. Create a branch to hold your changes:
```bash
git checkout -b my-feature
```

git checkout -b my-feature
and start making changes.

and start making changes. Never work in the ``main`` branch!
5. When you're done making changes, add changed files to the index with ``git add`` and
``git commit`` them with a descriptive message.

4. Work on this copy, on your computer, using Git to do the version
control. When you're done editing, do::
```bash
git add modified_files
git commit -m "A short description of the commit"
```

git add modified_files
git commit
6. Run the tests with ``pytest``. If they pass, you are ready to submit a pull request.

to record your changes in Git, then push them to Github with::
```bash
pytest test
```

git push -u origin my-feature
7. Push your changes to Github with:

Finally, go to the web page of the your fork of the repo,
and click 'Pull request' to send your changes to the maintainers for review.
```bash
git push -u origin my-feature
```

Finally, go to the web page of your fork of the repo,
and click ``Pull request`` to send your changes to the maintainers for review.

## Merge Policy

Summary: maintainer can push minor changes directly, pull request + 1 reviewer for everything else.

* Usually it is not possible to push directly to the `main` branch of *pathfinding3D* for anyone. Only tiny changes, urgent bugfixes, and maintenance commits can be pushed directly to the `main` branch by the maintainer without a review. "Tiny" means backwards compatibility is mandatory and all tests must succeed. No new feature must be added.
Usually, direct push to the main branch of pathfinding3D is restricted. Only minor changes, urgent bugfixes, and maintenance commits can be pushed directly to the main branch by the maintainer without a review. "Minor" implies backwards compatibility and successful completion of all tests. No new features must be added.

Developers should submit pull requests for their changes. PRs should be reviewed by at least one other developer and merged by the maintainer. New features must be documented and tested. Breaking changes must be discussed and announced in advance with deprecation warnings.

Contributors are encouraged to engage in the feedback and review process. If you haven't received any response on your PR within a reasonable timeframe, feel free to reach out for an update.

All contributions will be acknowledged, either through mentions in release notes, the contributor list, or other appropriate channels.

* Developers should submit pull requests. Those will ideally be reviewed by at least one other developer and merged by the maintainer. New features must be documented and tested. Breaking changes must be discussed and announced in advance with deprecation warnings.
By following these guidelines, you help maintain the quality and consistency of the pathfinding3D project. We appreciate your contributions and look forward to your active participation in our community.
2 changes: 1 addition & 1 deletion LICENSE
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
The MIT License (MIT)

Copyright (c) 2023 Harisankar Babu
Copyright (c) 2024 Harisankar Babu

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
Expand Down
102 changes: 76 additions & 26 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,74 +8,124 @@

Pathfinding algorithms for python3 froked from [python-pathfinding](https://github.com/brean/python-pathfinding) by [@brean](https://github.com/brean).

Pathfinding3D is a comprehensive library designed for 3D pathfinding applications.

Currently there are 7 path-finders bundled in this library, namely:

- A*
- Dijkstra
- A\*: Versatile and most widely used algorithm.
- Dijkstra: A\* without heuristic.
- Best-First
- Bi-directional A*
- Bi-directional A\*: Efficient for large graphs with a known goal.
- Breadth First Search (BFS)
- Iterative Deeping A\* (IDA*)
- Iterative Deeping A\* (IDA\*): Memory efficient algorithm for large graphs.
- Minimum Spanning Tree (MSP)

Dijkstra, A\* and Bi-directional A\* take the weight of the fields on the map into account.

## Installation

The package is available on pypi, so you can install it with pip:
### Requirements

- python >= 3.8
- numpy

To install Pathfinding3D, use pip:

```bash
pip install pathfinding3d
```

see [pathfinding3d on pypi](https://pypi.org/project/pathfinding3d/)
For more details, see [pathfinding3d on pypi](https://pypi.org/project/pathfinding3d/)

## Usage examples

For usage examples with detailed descriptions take a look at the [examples](examples/) folder, also take a look at the [test/](test/) folder for more examples.
For a quick start, here's a basic example:

```python
import numpy as np

from pathfinding3d.core.diagonal_movement import DiagonalMovement
from pathfinding3d.core.grid import Grid
from pathfinding3d.finder.a_star import AStarFinder

# Create a 3D numpy array with 0s as obstacles and 1s as walkable paths
matrix = np.ones((10, 10, 10), dtype=np.int8)
# mark the center of the grid as an obstacle
matrix[5, 5, 5] = 0

# Create a grid object from the numpy array
grid = Grid(matrix=matrix)

# Mark the start and end points
start = grid.node(0, 0, 0)
end = grid.node(9, 9, 9)

# Create an instance of the A* finder with diagonal movement allowed
finder = AStarFinder(diagonal_movement=DiagonalMovement.always)
path, runs = finder.find_path(start, end, grid)

## Rerun the algorithm
# Path will be a list with all the waypoints as nodes
# Convert it to a list of coordinate tuples
path = [p.identifier for p in path]

While running the pathfinding algorithm it might set values on the nodes. Depending on your path finding algorithm things like calculated distances or visited flags might be stored on them. So if you want to run the algorithm in a loop you need to clean the grid first (see `Grid.cleanup`). Please note that because cleanup looks at all nodes of the grid it might be an operation that can take a bit of time!
print("operations:", runs, "path length:", len(path))
print("path:", path)
```

For usage examples with detailed descriptions take a look at the [examples](examples/) folder.

## Rerun the Algorithm

When rerunning the algorithm, remember to clean the grid first using `Grid.cleanup`. This will reset the grid to its original state.

```python
grid.cleanup()
```

Please note that this operation can be time-consuming but is usally faster than creating a new grid object.

## Implementation details

All pathfinding algorithms in this library are inheriting the Finder class. It has some common functionality that can be overwritten by the implementation of a path finding algorithm.
All pathfinding algorithms in this library inherit from the `Finder` class. This class provides common functionality that can be overridden by specific pathfinding algorithm implementations.

The normal process works like this:
General Process:

1. You call `find_path` on one of your finder implementations.
1. `init_find` instantiates the `open_list` and resets all values and counters.
1. The main loop starts on the `open_list`. This list gets filled with all nodes that will be processed next (e.g. all current neighbors that are walkable). For this you need to implement `check_neighbors` in your own finder implementation.
1. For example in A\*s implementation of `check_neighbors` you first want to get the next node closest from the current starting point from the open list. the `next_node` method in Finder does this by giving you the node with a minimum `f`-value from the open list, it closes it and removes it from the `open_list`.
1. if this node is not the end node we go on and get its neighbors by calling `find_neighbors`. This just calls `grid.neighbors` for most algorithms.
1. If none of the neighbors are the end node we want to process the neighbors to calculate their distances in `process_node`
1. `process_node` calculates the cost `f` from the start to the current node using the `calc_cost` method and the cost after calculating `h` from `apply_heuristic`.
1. finally `process_node` updates the open list so `find_path` can run `check_neighbors` on it in the next node in the next iteration of the main loop.
2. `init_find` instantiates the `open_list` and resets all values and counters. The `open_list` is a priority queue that keeps track of nodes to be explored.
3. The main loop starts on the `open_list` which contains all nodes to be processed next (e.g. all current neighbors that are walkable). You need to implement `check_neighbors` in your finder implementation to fill this list.
4. For example in A\* implementation (`AStarFinder`), `check_neighbors` pops the node with the minimum 'f' value from the open list and marks it as closed. It then either returns the path (if the end node is reached) or continues processing neighbors.
5. If the end node is not reached, `check_neighbors` calls `find_neighbors` to get all adjacent walkable nodes. For most algorithms, this calls `grid.neighbors`.
6. If none of the neighbors are walkable, the algorithm terminates. Otherwise, `check_neighbors` calls `process_node` on each neighbor. It calculates the cost `f` for each neighbor node. This involves computing `g` (the cost from the start node to the current node) and `h` (the estimated cost from the current node to the end node, calculated by `apply_heuristic`).
7. Finally `process_node` updates the open list so `find_path` with new or updated nodes. This allows `find_path` to continue the process with the next node in the subsequent iteration.

flow:

```pseudo
find_path
init_find # (re)set global values and open list
check_neighbors # for every node in open list
next_node # closest node to start in open list
find_neighbors # get neighbors
process_node # calculate new cost for neighboring node
while open_list not empty:
check_neighbors # for the node with min 'f' value in open list
pop_node # node with min 'f' value
find_neighbors # get neighbors
process_node # calculate new cost for each neighbor
```

## Testing

You can run the tests locally using pytest. Take a look at the `test`-folder
Run the tests locally using pytest. For detailed instructions, see the `test` folder:

```bash
pytest test
```

## Contributing

Please use the [issue tracker](https://github.com/harisankar95/pathfinding3D/issues) to submit bug reports and feature requests. Please use merge requests as described [here](/CONTRIBUTING.md) to add/adapt functionality.
We welcome contributions of all sizes and levels! For bug reports and feature requests, please use the [issue tracker](https://github.com/harisankar95/pathfinding3D/issues) to submit bug reports and feature requests. Please Follow the guidelines in [CONTRIBUTING.md](/CONTRIBUTING.md) for submitting merge requests.

## License

python-pathfinding is distributed under the [MIT license](https://opensource.org/licenses/MIT).
Pathfinding3D is distributed under the [MIT license](https://opensource.org/licenses/MIT).

## Authors / Contributers

Authors and contributers are [listed on github](https://github.com/harisankar95/pathfinding3D/graphs/contributors).
Find a list of contributors [here](https://github.com/harisankar95/pathfinding3D/graphs/contributors).
8 changes: 7 additions & 1 deletion docs/INSTALL.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,10 @@
# Installation

## Requirements

- python - 3.8 or higher
- numpy

## PyPI

The package is available on pypi, so you can install it with pip:
Expand All @@ -8,10 +13,11 @@ The package is available on pypi, so you can install it with pip:
pip install pathfinding3d
```

## For development purpose use editable mode
## For development purposes please use editable mode

```bash
git clone https://github.com/harisankar95/pathfinding3D
cd pathfinding3D
pip install -e .[dev]
git checkout -b <branch_name>
```
10 changes: 6 additions & 4 deletions docs/INTRO.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,16 @@

Pathfinding algorithms for python3 froked from [python-pathfinding](https://github.com/brean/python-pathfinding) by [@brean](https://github.com/brean).

Pathfinding3D is a comprehensive library designed for 3D pathfinding applications.

Currently there are 7 path-finders bundled in this library, namely:

- A*
- Dijkstra
- A\*: Versatile and most widely used algorithm.
- Dijkstra: A\* without heuristic.
- Best-First
- Bi-directional A*
- Bi-directional A\*: Efficient for large graphs with a known goal.
- Breadth First Search (BFS)
- Iterative Deeping A\* (IDA*)
- Iterative Deeping A\* (IDA\*): Memory efficient algorithm for large graphs.
- Minimum Spanning Tree (MSP)

Dijkstra, A\* and Bi-directional A\* take the weight of the fields on the map into account.
Loading

0 comments on commit 348c06a

Please sign in to comment.