Added early exit to BFS, added Dijkstra class
This commit is contained in:
parent
b7ccb7c2cc
commit
0cd01ece0c
@ -205,8 +205,9 @@ class DFS(PathFinderBase):
|
|||||||
|
|
||||||
class BFS(PathFinderBase):
|
class BFS(PathFinderBase):
|
||||||
"""
|
"""
|
||||||
Iterative breadh-first search. Finds optimal path and creates flow-field,
|
Iterative breadth-first search
|
||||||
so it would be good match for static maps with lots of agents with one
|
Finds optimal path and creates flow-field, does not take the node cost into account.
|
||||||
|
This would be good match for static maps with lots of agents with one
|
||||||
destination.
|
destination.
|
||||||
Compared to A*, this is more computationally expensive if we only want
|
Compared to A*, this is more computationally expensive if we only want
|
||||||
to find path for one agent.
|
to find path for one agent.
|
||||||
@ -224,14 +225,19 @@ class BFS(PathFinderBase):
|
|||||||
self._distance: dict[Point2D, float] = { end_point: 0.0 }
|
self._distance: dict[Point2D, float] = { end_point: 0.0 }
|
||||||
|
|
||||||
# build "flow map"
|
# build "flow map"
|
||||||
while not frontier.empty():
|
early_exit = False
|
||||||
|
while not frontier.empty() and not early_exit:
|
||||||
current = frontier.get()
|
current = frontier.get()
|
||||||
for next_point in self._map.GetNeighbours(current):
|
for next_point in self._map.GetNeighbours(current):
|
||||||
if next_point not in self._came_from:
|
if next_point not in self._came_from:
|
||||||
frontier.put(next_point)
|
frontier.put(next_point)
|
||||||
#self._distance[next_point] = self._distance[current] + 1.0
|
self._distance[next_point] = self._distance[current] + 1.0
|
||||||
self._distance[next_point] = self._distance[current] + self._map.Visit(next_point)
|
_ = self._map.Visit(next_point) # visit only to track visited node count
|
||||||
self._came_from[next_point] = current
|
self._came_from[next_point] = current
|
||||||
|
if next_point == start_point:
|
||||||
|
# early exit - if you want to build the whole flow field, remove this
|
||||||
|
early_exit = True
|
||||||
|
break
|
||||||
# find actual path
|
# find actual path
|
||||||
path: Path = []
|
path: Path = []
|
||||||
current = start_point
|
current = start_point
|
||||||
@ -240,12 +246,24 @@ class BFS(PathFinderBase):
|
|||||||
current = self._came_from[current]
|
current = self._came_from[current]
|
||||||
path.append(current)
|
path.append(current)
|
||||||
return path
|
return path
|
||||||
|
|
||||||
|
|
||||||
|
class Dijkstra(PathFinderBase):
|
||||||
|
"""
|
||||||
|
Like BFS, but takes into account cost of nodes
|
||||||
|
"""
|
||||||
|
|
||||||
|
name = "Dijkstra"
|
||||||
|
|
||||||
|
def _CalculatePath(self, start_point: Point2D, end_point: Point2D) -> Optional[Path]:
|
||||||
|
...
|
||||||
|
|
||||||
class A_star(PathFinderBase):
|
class A_star(PathFinderBase):
|
||||||
|
|
||||||
name = "A*"
|
name = "A*"
|
||||||
|
|
||||||
|
def _CalculatePath(self, start_point: Point2D, end_point: Point2D) -> Optional[Path]:
|
||||||
|
...
|
||||||
#
|
#
|
||||||
# Calculate paths using various methods and visualize them
|
# Calculate paths using various methods and visualize them
|
||||||
#
|
#
|
||||||
@ -254,12 +272,14 @@ def main():
|
|||||||
# Define the map and start/stop points
|
# Define the map and start/stop points
|
||||||
m = Map(15,10)
|
m = Map(15,10)
|
||||||
m.Randomize()
|
m.Randomize()
|
||||||
starting_point: Point2D = Point2D((14,8))
|
starting_point: Point2D = Point2D((1,1))
|
||||||
end_point: Point2D = Point2D((1,1))
|
end_point: Point2D = Point2D((5,5))
|
||||||
|
|
||||||
path_finder_classes: list[type[PathFinderBase]] = [
|
path_finder_classes: list[type[PathFinderBase]] = [
|
||||||
DFS,
|
DFS,
|
||||||
BFS,
|
BFS,
|
||||||
|
Dijkstra,
|
||||||
|
A_star
|
||||||
]
|
]
|
||||||
|
|
||||||
v = Visualizer()
|
v = Visualizer()
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user