[2] feat - три алгоритма поиска пути (BFS, DFS, A*)

This commit is contained in:
semyanovra 2026-05-24 14:07:25 +00:00
parent 735626045b
commit acbd3a3892

View File

@ -149,7 +149,115 @@ class TxtLabyrinthBuilder(LabyrinthBuilder):
return lab
# ----------------------------- Алгоритмы поиска -----------------------------
class SearchAlgorithm:
def compute_path(self, maze, start, goal):
raise NotImplementedError
def _build_path(self, came_from, start, goal):
path = []
cur = goal
while cur is not None:
path.append(cur)
cur = came_from.get(cur)
path.reverse()
return path
def visited_nodes(self):
return getattr(self, '_visited', 0)
class BFS(SearchAlgorithm):
def compute_path(self, maze, start, goal):
q = deque()
q.append(start)
came_from = {start: None}
visited = {start}
while q:
cur = q.popleft()
if cur == goal:
self._visited = len(visited)
return self._build_path(came_from, start, goal)
for nb in maze.adjacent_cells(cur):
if nb not in visited:
visited.add(nb)
came_from[nb] = cur
q.append(nb)
self._visited = len(visited)
return []
class DFS(SearchAlgorithm):
def compute_path(self, maze, start, goal):
stack = [start]
came_from = {start: None}
visited = {start}
while stack:
cur = stack.pop()
if cur == goal:
self._visited = len(visited)
return self._build_path(came_from, start, goal)
for nb in maze.adjacent_cells(cur):
if nb not in visited:
visited.add(nb)
came_from[nb] = cur
stack.append(nb)
self._visited = len(visited)
return []
class AStar(SearchAlgorithm):
def _heuristic(self, cell, goal):
return abs(cell.x - goal.x) + abs(cell.y - goal.y)
def compute_path(self, maze, start, goal):
heap = []
counter = 0
start_f = self._heuristic(start, goal)
heapq.heappush(heap, (start_f, counter, start))
counter += 1
came_from = {}
g_score = {start: 0}
f_score = {start: start_f}
visited = set()
while heap:
cur_f, _, cur = heapq.heappop(heap)
visited.add(cur)
if cur == goal:
self._visited = len(visited)
return self._build_path(came_from, start, goal)
if cur_f > f_score.get(cur, float('inf')):
continue
for nb in maze.adjacent_cells(cur):
tentative_g = g_score[cur] + 1
if tentative_g < g_score.get(nb, float('inf')):
came_from[nb] = cur
g_score[nb] = tentative_g
new_f = tentative_g + self._heuristic(nb, goal)
f_score[nb] = new_f
heapq.heappush(heap, (new_f, counter, nb))
counter += 1
self._visited = len(visited)
return []
if __name__ == "__main__":
builder = TxtLabyrinthBuilder()
maze = builder.build_from_file("maze/level1.txt")
print(f"Maze loaded: {maze.width}x{maze.height}")
bfs = BFS()
path = bfs.compute_path(maze, maze.start, maze.exit)
print(f"BFS path length: {len(path)}")
dfs = DFS()
path = dfs.compute_path(maze, maze.start, maze.exit)
print(f"DFS path length: {len(path)}")
astar = AStar()
path = astar.compute_path(maze, maze.start, maze.exit)
print(f"A* path length: {len(path)}")