Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion pathfinding/finder/__init__.py
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
__all__ = ['a_star', 'best_first', 'bi_a_star', 'bi_breadth_first',
'breadth_first', 'dijkstra', 'finder', 'ida_star']
'bi_best_first', 'bi_dijkstra', 'breadth_first', 'dijkstra',
'finder', 'ida_star']
46 changes: 46 additions & 0 deletions pathfinding/finder/bi_best_first.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
from .bi_a_star import BiAStarFinder
from ..core.diagonal_movement import DiagonalMovement
from .finder import TIME_LIMIT, MAX_RUNS


class BiBestFirstFinder(BiAStarFinder):
"""
Bi-directional Best-First-Search algorithm.
It is essentially the same as bi-directional A* but with a high weight
on the heuristic, making it a greedy search.
"""

def __init__(
self,
heuristic=None,
weight=1,
diagonal_movement=DiagonalMovement.never,
time_limit=TIME_LIMIT,
max_runs=MAX_RUNS,
):
"""
:param heuristic: heuristic used to calculate distance of 2 points
(defaults to manhattan)
:param weight: weight for the edges
:param diagonal_movement: if diagonal movement is allowed
(see enum in diagonal_movement)
:param time_limit: max. runtime in seconds
:param max_runs: max. amount of tries until we abort the search
"""
super(BiBestFirstFinder, self).__init__(
heuristic=heuristic,
weight=weight,
diagonal_movement=diagonal_movement,
time_limit=time_limit,
max_runs=max_runs,
)

self.weighted = False

def apply_heuristic(self, node_a, node_b, heuristic=None, graph=None):
return (
super(BiBestFirstFinder, self).apply_heuristic(
node_a, node_b, heuristic, graph=graph
)
* 1000000
)
39 changes: 39 additions & 0 deletions pathfinding/finder/bi_dijkstra.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
from .bi_a_star import BiAStarFinder
from ..core.diagonal_movement import DiagonalMovement
from .finder import TIME_LIMIT, MAX_RUNS
from ..core.heuristic import null


class BiDijkstraFinder(BiAStarFinder):
"""
Bi-directional Dijkstra's algorithm.

It is similar to bi-directional A* but with a heuristic of zero.
This means the search expands purely based on the lowest cost from the
start and end points.
"""

def __init__(
self,
weight=1,
diagonal_movement=DiagonalMovement.never,
time_limit=TIME_LIMIT,
max_runs=MAX_RUNS,
):
"""
:param weight: weight for the edges
:param diagonal_movement: if diagonal movement is allowed
(see enum in diagonal_movement)
:param time_limit: max. runtime in seconds
:param max_runs: max. amount of tries until we abort the search
"""
super(BiDijkstraFinder, self).__init__(
heuristic=null,
weight=weight,
diagonal_movement=diagonal_movement,
time_limit=time_limit,
max_runs=max_runs,
)

def apply_heuristic(self, node_a, node_b, heuristic=None, graph=None):
return 0
9 changes: 6 additions & 3 deletions test/test_path.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,15 @@
from pathfinding.finder.a_star import AStarFinder
from pathfinding.finder.best_first import BestFirst
from pathfinding.finder.bi_a_star import BiAStarFinder
from pathfinding.finder.bi_breadth_first import BiBreadthFirstFinder
from pathfinding.finder.bi_best_first import BiBestFirstFinder
from pathfinding.finder.bi_dijkstra import BiDijkstraFinder
from pathfinding.finder.breadth_first import BreadthFirstFinder
from pathfinding.finder.dijkstra import DijkstraFinder
from pathfinding.finder.finder import ExecutionRunsException
from pathfinding.finder.finder import ExecutionTimeException
from pathfinding.finder.ida_star import IDAStarFinder
from pathfinding.finder.msp import MinimumSpanningTree
from pathfinding.finder.bi_breadth_first import BiBreadthFirstFinder

import pytest

Expand All @@ -22,8 +24,9 @@
# test scenarios from Pathfinding.JS
scenarios = os.path.join(BASE_PATH, 'path_test_scenarios.json')
data = json.load(open(scenarios, 'r', encoding='utf-8'))
finders = [AStarFinder, BestFirst, BiAStarFinder, BiBreadthFirstFinder,
DijkstraFinder, IDAStarFinder, BreadthFirstFinder, MinimumSpanningTree]
finders = [AStarFinder, BestFirst, BiAStarFinder, BiBreadthFirstFinder,
BiBestFirstFinder, BiDijkstraFinder, DijkstraFinder, IDAStarFinder,
BreadthFirstFinder, MinimumSpanningTree]
TIME_LIMIT = 10 # give it a 10 second limit.


Expand Down