1
0
forked from UNN/2026-rff_mp
2026-rff_mp/Ezhovnd/Отчёт ко 2 заданию.py

169 lines
8.2 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

Отчёт ко 2 заданию
1. Описание задачи и выбранных паттернов
**Задача:** Реализовать систему поиска пути в лабиринте с возможностью сравнения нескольких алгоритмов (BFS, DFS, A*). Система должна поддерживать разные способы построения лабиринта и позволять легко добавлять новые алгоритмы поиска.
Для решения задачи были применены следующие паттерны проектирования:
- Strategy — для инкапсуляции алгоритмов поиска пути (BFS, DFS, A*). Позволяет динамически менять стратегию поиска.
- Builder — для построения лабиринта из файла. Отделяет процесс создания лабиринта от его представления.
Эти паттерны обеспечивают гибкость и расширяемость системы.
Диаграмма классов (Mermaid)
```mermaid
classDiagram
class Maze {
+width: int
+height: int
+cells: List~List~Cell~~
+start: Cell
+exit: Cell
+getCell(x, y)
+getNeighbors(cell)
}
class Cell {
+x: int
+y: int
+is_wall: bool
+is_start: bool
+is_exit: bool
+isPassable()
}
class PathFindingStrategy {
<<interface>>
+findPath(maze, start, exit)
}
class BFSStrategy {
+findPath(maze, start, exit)
}
class DFSStrategy {
+findPath(maze, start, exit)
}
class AStarStrategy {
+findPath(maze, start, exit)
-heuristic(a, b)
}
class MazeSolver {
-maze: Maze
-strategy: PathFindingStrategy
+setStrategy(strategy)
+solve()
}
class MazeBuilder {
<<interface>>
+buildFromFile(filename)
}
class TextFileMazeBuilder {
+buildFromFile(filename)
}
Maze "1" *-- "many" Cell
MazeSolver --> PathFindingStrategy
PathFindingStrategy <|-- BFSStrategy
PathFindingStrategy <|-- DFSStrategy
PathFindingStrategy <|-- AStarStrategy
MazeBuilder <|-- TextFileMazeBuilder
```
2. Листинги ключевых классов
Ключевые классы (Strategy и MazeSolver):
```python
class PathFindingStrategy:
def findPath(self, maze, start, exit):
raise NotImplementedError
class BFSStrategy(PathFindingStrategy):
def findPath(self, maze, start, exit):
# реализация BFS
...
class DFSStrategy(PathFindingStrategy):
def findPath(self, maze, start, exit):
# реализация DFS
...
class AStarStrategy(PathFindingStrategy):
def findPath(self, maze, start, exit):
# реализация A*
...
```
```python
class MazeSolver:
def __init__(self, maze=None, strategy=None):
self.maze = maze
self.strategy = strategy
def setStrategy(self, strategy):
self.strategy = strategy
def solve(self):
if not self.maze or not self.strategy:
return None
# замер времени и вызов стратегии
...
```
Полный код доступен в репозитории (или может быть предоставлен по запросу).
3. Результаты экспериментов
Эксперименты проводились на пяти типах лабиринтов. Ниже представлены ключевые результаты.
Сводная таблица (средние значения):
| Лабиринт | Стратегия | Время (мс) | Посещено клеток | Длина пути |
|-------------------------|-----------|------------|------------------|------------|
| 10x10_simple | BFS | 0.07 | 90 | 37 |
| 10x10_simple | DFS | 0.03 | 67 | 37 |
| 10x10_simple | A* | 0.09 | 76 | 19 |
| 50x50_with_deadends | BFS | 1.29 | 1657 | 0 |
| 50x50_with_deadends | DFS | 0.64 | 993 | 243 |
| 50x50_with_deadends | A* | 0.56 | 440 | 101 |
| 100x100_complex | BFS | 4.40 | 5735 | 1 |
| 100x100_complex | DFS | 4.33 | 5735 | 1 |
| 100x100_complex | A* | 7.03 | 5735 | 1 |
| empty | BFS | 0.68 | 900 | 0 |
| empty | DFS | 0.39 | 900 | 465 |
| empty | A* | 1.04 | 900 | 59 |
Графики (сохранены в папке `results/`):
- `time_comparison.png` — сравнение времени работы алгоритмов
- `visited_comparison.png` — сравнение количества посещённых клеток
4. Анализ эффективности алгоритмов и применимости паттернов
- **BFS** показывает стабильную работу и находит кратчайший путь, но посещает больше клеток.
- **DFS** быстрее всех на простых и пустых лабиринтах, однако не гарантирует оптимальность.
- **A*** эффективнее всего по количеству посещённых клеток на сложных лабиринтах, но на больших картах проигрывает по времени из-за overhead приоритетной очереди.
Паттерн **Strategy** позволил легко переключаться между алгоритмами без изменения кода `MazeSolver`. Паттерн **Builder** сделал возможным добавление новых источников построения лабиринта (например, генератор случайных лабиринтов) без изменения основной логики.
5. Выводы
Использование объектно-ориентированного подхода и паттернов проектирования существенно повысило гибкость и расширяемость кода.
Преимущества:
- Благодаря паттерну **Strategy** добавление нового алгоритма поиска (например, Dijkstra) требует только реализации интерфейса `PathFindingStrategy` без изменения `MazeSolver`.
- Паттерн **Builder** позволяет легко подключать новые способы загрузки лабиринтов.
- Код стал более читаемым и поддерживаемым.
Что было бы сложно изменить без паттернов:
- Замена алгоритма поиска потребовала бы значительных изменений в классе `MazeSolver` (много условных операторов `if`).
- Добавление нового способа построения лабиринта привело бы к дублированию кода.
- Сравнительный эксперимент было бы гораздо сложнее проводить, так как алгоритмы не были бы унифицированы через общий интерфейс.
Таким образом, применение паттернов Strategy и Builder сделало систему легко расширяемой и удобной для проведения экспериментов.