forked from UNN/2026-rff_mp
[2] feat - три алгоритма поиска пути (BFS, DFS, A*)
This commit is contained in:
parent
735626045b
commit
acbd3a3892
|
|
@ -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)}")
|
||||
Loading…
Reference in New Issue
Block a user