Реализован Этап 5

This commit is contained in:
oSTEVEo 2026-05-23 12:02:30 +03:00
parent 107d5cbd61
commit 74928a997a
6 changed files with 60 additions and 9 deletions

View File

@ -0,0 +1,4 @@
class Path:
def __init__(self, array:list[Cell]|None, visited_cells:int):
self.array = array
self.visited_cells = visited_cells

View File

@ -0,0 +1,43 @@
from task2.mazeObjects.maze import Maze
from task2.mazeObjects.cell import Cell
from task2.strategyObjects.pathFindingStrategy import PathFindingStrategy
import time
class SearchStats:
"""Время выполнения в миллисекундах, количество посещённых клеток, длина найденного пути"""
def __init__(self, path: list[Cell]|None, duration:float, visited_cells:int, path_len:int, strategy_name:str):
self.duration = duration
self.visited_cells = visited_cells
self.path_len = path_len
self.path = path
self.strategy_name = strategy_name
class MazeSolver:
"""
MazeSolver содержит поля maze и strategy.
Метод setStrategy(strategy) для динамической смены алгоритма.
Метод solve() вызывает strategy.findPath(...) и возвращает объект SearchStats (время выполнения в миллисекундах,
количество посещённых клеток, длина найденного пути).
Для замера времени используйте time.perf_counter() до и после вызова стратегии.
"""
def __init__(self, maze:Maze, strategy:PathFindingStrategy):
self.maze = maze
self.strategy = strategy
def setStrategy(self, strategy:PathFindingStrategy):
self.strategy = strategy
def getStrategyName(self):
return self.strategy.__class__.__name__
def solve(self):
t_start = time.perf_counter()
path = self.strategy.findPath(self.maze, self.maze.startCell, self.maze.endCell)
duration = time.perf_counter() - t_start
path_len = len(path.array) if path.array else 0
strategy_name = self.getStrategyName()
return SearchStats(path.array, duration, path.visited_cells, path_len, strategy_name)

View File

@ -6,13 +6,14 @@ from task2.strategyObjects.util import restorePath
from task2.mazeObjects.maze import Maze from task2.mazeObjects.maze import Maze
from task2.mazeObjects.cell import Cell from task2.mazeObjects.cell import Cell
from task2.mazeObjects.path import Path
class AStar(PathFindingStrategy): class AStar(PathFindingStrategy):
"""Алгоритм с эвристикой (etc. манхэттенское расстояние) компромисс между скоростью и оптимальностью.""" """Алгоритм с эвристикой (etc. манхэттенское расстояние) компромисс между скоростью и оптимальностью."""
def heuristic(self, first: Cell, second: Cell) -> int: def heuristic(self, first: Cell, second: Cell) -> int:
return abs(first.x - second.x) + abs(first.y - second.y) return abs(first.x - second.x) + abs(first.y - second.y)
def findPath(self, maze: Maze, start: Cell, exit: Cell): def findPath(self, maze: Maze, start: Cell, exit: Cell) -> Path:
tie_breaker = count() tie_breaker = count()
start_heuristic = self.heuristic(start, exit) start_heuristic = self.heuristic(start, exit)
heap: list[tuple[int, int, int, Cell]] = [ heap: list[tuple[int, int, int, Cell]] = [
@ -29,7 +30,7 @@ class AStar(PathFindingStrategy):
visited.add(current) visited.add(current)
if current == exit: if current == exit:
return restorePath(parents, exit) return Path(restorePath(parents, exit), len(visited))
for neighbor in maze.getNeighbors(current): for neighbor in maze.getNeighbors(current):
tentative_score = g_score[current] tentative_score = g_score[current]
@ -42,4 +43,4 @@ class AStar(PathFindingStrategy):
heap, heap,
(priority, heuristic, next(tie_breaker), neighbor), (priority, heuristic, next(tie_breaker), neighbor),
) )
return [] return Path(None, len(visited))

View File

@ -3,13 +3,14 @@ from task2.strategyObjects.util import restorePath
from task2.mazeObjects.maze import Maze from task2.mazeObjects.maze import Maze
from task2.mazeObjects.cell import Cell from task2.mazeObjects.cell import Cell
from task2.mazeObjects.path import Path
import queue import queue
class BFS(PathFindingStrategy): class BFS(PathFindingStrategy):
"""Поиск в ширину гарантирует кратчайший путь по количеству шагов. """Поиск в ширину гарантирует кратчайший путь по количеству шагов.
Возвращает None, если пути нет""" Возвращает None, если пути нет"""
def findPath(self, maze: Maze, start: Cell, exit: Cell): def findPath(self, maze: Maze, start: Cell, exit: Cell) -> Path:
visited = dict() visited = dict()
parents = dict() parents = dict()
q = queue.Queue() q = queue.Queue()
@ -31,4 +32,5 @@ class BFS(PathFindingStrategy):
visited[hood] = visited[current] + 1 visited[hood] = visited[current] + 1
parents[hood] = current parents[hood] = current
q.put(hood) q.put(hood)
return restorePath(parents, exit)
return Path(restorePath(parents, exit), len(visited))

View File

@ -3,12 +3,12 @@ from task2.strategyObjects.util import restorePath
from task2.mazeObjects.maze import Maze from task2.mazeObjects.maze import Maze
from task2.mazeObjects.cell import Cell from task2.mazeObjects.cell import Cell
from task2.mazeObjects.path import Path
class DFS(PathFindingStrategy): class DFS(PathFindingStrategy):
"""Поиск в глубину быстрый, но не обязательно кратчайший. """Поиск в глубину быстрый, но не обязательно кратчайший.
Возвращает None, если пути нет""" Возвращает None, если пути нет"""
def findPath(self, maze: Maze, start: Cell, exit: Cell): def findPath(self, maze: Maze, start: Cell, exit: Cell) -> Path:
visited = dict() visited = dict()
parents = dict() parents = dict()
stack = [] stack = []
@ -31,4 +31,4 @@ class DFS(PathFindingStrategy):
parents[hood] = current parents[hood] = current
stack.append(hood) stack.append(hood)
return restorePath(parents, exit) return Path(restorePath(parents, exit), len(visited))

View File

@ -2,12 +2,13 @@ from abc import ABC, abstractmethod
from task2.mazeObjects.maze import Maze from task2.mazeObjects.maze import Maze
from task2.mazeObjects.cell import Cell from task2.mazeObjects.cell import Cell
from task2.mazeObjects.path import Path
class PathFindingStrategy(ABC): class PathFindingStrategy(ABC):
"""Интерфейс PathFindingStrategy с методом findPath(maze, start, exit), """Интерфейс PathFindingStrategy с методом findPath(maze, start, exit),
возвращающим список клеток пути (от старта до выхода включительно) или пустой список, если пути нет.""" возвращающим список клеток пути (от старта до выхода включительно) или пустой список, если пути нет."""
@abstractmethod @abstractmethod
def findPath(self, maze: Maze, start: Cell, exit: Cell): def findPath(self, maze: Maze, start: Cell, exit: Cell) -> Path:
"""Возвращает список клеток пути от старта до выхода включительно. Пути нет - пустой список.""" """Возвращает список клеток пути от старта до выхода включительно. Пути нет - пустой список."""
raise NotImplementedError raise NotImplementedError