2026-rff_mp/KislyuninED/docks/report-2-nd.md

136 lines
11 KiB
Markdown
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.

# Лабораторная работа: Поиск выхода из лабиринта
## 1. Постановка задачи
Требуется разработать приложение, которое загружает лабиринт из текстового файла, находит путь от стартовой клетки до выхода с возможностью выбора алгоритма поиска, отображает процесс и проводит экспериментальное сравнение алгоритмов.
### Ключевые требования:
- Создать модель лабиринта (классы `Cell`, `Maze`)
- Реализовать загрузку лабиринта из файла с символами `#` (стена), `S` (старт), `E` (выход)
- Реализовать три алгоритма поиска: BFS, DFS, A*
- Создать класс-оркестратор `MazeSolver` с возможностью смены стратегии
- Собирать статистику: время выполнения, количество посещённых клеток, длина пути
- Провести эксперименты на лабиринтах разного размера и сложности
### Применённые паттерны проектирования GoF:
#### 1. Строитель (Builder)
- **Где используется:** классы `MazeBuilder` и `TextFileMazeBuilder`
- **Обоснование:** создание лабиринта из файла включает парсинг, валидацию и установку старта/выхода. Строитель скрывает эти детали и упрощает добавление новых форматов.
- **Плюсы:** новый формат файла требует только создания ещё одного строителя, не затрагивая остальные классы.
#### 2. Стратегия (Strategy)
- **Где используется:** классы `PathFindingStrategy`, `BFSStrategy`, `DFSStrategy`, `AStarStrategy`
- **Обоснование:** алгоритмы поиска взаимозаменяемы и решают одну задачу разными способами. Стратегия позволяет менять алгоритм во время выполнения и легко добавлять новые.
- **Плюсы:** класс `MazeSolver` может использовать любую стратегию через `set_strategy`. Новый алгоритм требует только создания нового класса.
#### 3. Наблюдатель (Observer)
- **Где используется:** классы `Observer` и `ConsoleView`
- **Обоснование:** приложение должно обновлять консольный интерфейс при различных событиях. Наблюдатель отделяет логику отображения от логики приложения.
- **Плюсы:** легко добавить новые виды отображения без изменения основной логики.
#### 4. Команда (Command)
- **Где используется:** классы `Command` и `MoveCommand`
- **Обоснование:** для пошагового перемещения игрока с возможностью отмены действий. Команда инкапсулирует действие в объект и позволяет реализовать undo/redo.
- **Плюсы:** хранение истории действий и возможность отмены последних ходов без изменения класса `Player`.
## 2. Архитектура приложения
Приложение состоит из следующих компонентов:
- **Модель:** классы `Cell` и `Maze` - представляют клетку и лабиринт.
- **Загрузка:** классы `MazeBuilder` и `TextFileMazeBuilder` - загрузка из файлов.
- **Алгоритмы:** классы `BFSStrategy`, `DFSStrategy`, `AStarStrategy`, реализующие `PathFindingStrategy`.
- **Оркестрация:** класс `MazeSolver`, управляющий процессом поиска.
- **Визуализация:** класс `ConsoleView`, реализующий `Observer`.
- **Управление:** классы `Command` и `MoveCommand` для пошагового движения.
- **Игрок:** класс `Player`, хранящий текущую позицию.
## 3. Реализация алгоритмов поиска
### BFS (поиск в ширину)
Использует очередь. Начинает со стартовой клетки, помещает её в очередь, затем циклически извлекает клетку из начала, проверяет, не является ли она выходом, и добавляет всех непосещённых соседей в конец. Гарантирует нахождение кратчайшего пути по числу шагов.
### DFS (поиск в глубину)
Использует стек. Начинает со стартовой клетки, помещает её в стек, затем циклически извлекает клетку из конца, проверяет на выход и добавляет непосещённых соседей в стек. Не гарантирует кратчайший путь, но обычно быстрее и экономичнее по памяти.
### A* (А звездочка)
Использует приоритетную очередь с эвристикой. Оценивает клетки по формуле `f = g + h`, где `g` - реальная стоимость пути от старта, `h` - эвристическое расстояние до выхода (манхэттенское расстояние). Находит кратчайший путь при допустимой эвристике и часто быстрее BFS.
## 4. Экспериментальная часть
### Тестовые лабиринты
- `maze1.txt` (10x6) простой лабиринт из задания.
- `maze10x10.txt` (10x10) лабиринт среднего размера со случайными стенами.
- `maze20x20.txt` (20x20) большой запутанный лабиринт.
- `maze_empty.txt` (15x15) пустой лабиринт без стен.
- `maze_no_exit.txt` (10x10) лабиринт без достижимого выхода.
### Результаты замеров
Каждый эксперимент проводился 5 раз, значения усреднены.
| Лабиринт | Алгоритм | Время (мс) | Посещено клеток | Длина пути |
|----------------|----------|------------|-----------------|------------|
| Small 10x6 | BFS | 0.040 | 27 | 14 |
| Small 10x6 | DFS | 0.025 | 27 | 18 |
| Small 10x6 | A* | 0.051 | 19 | 14 |
| Medium 10x10 | BFS | 0.023 | 19 | 12 |
| Medium 10x10 | DFS | 0.018 | 18 | 12 |
| Medium 10x10 | A* | 0.037 | 12 | 12 |
| Large 20x20 | BFS | 0.019 | 16 | 5 |
| Large 20x20 | DFS | 0.019 | 17 | 9 |
| Large 20x20 | A* | 0.023 | 9 | 5 |
| Empty 15x15 | BFS | 0.182 | 78 | 15 |
| Empty 15x15 | DFS | 0.069 | 76 | 43 |
| Empty 15x15 | A* | 0.156 | 63 | 15 |
| No exit 10x10 | BFS | | | 0 |
| No exit 10x10 | DFS | | | 0 |
| No exit 10x10 | A* | | | 0 |
### Графики
![Сравнение алгоритмов](algorithm_comparison.png)
На графике показано сравнение трёх алгоритмов по трём метрикам: время выполнения, количество посещённых клеток и длина найденного пути.
## 5. Анализ результатов
### Сравнение характеристик
**BFS:**
- Гарантия кратчайшего пути: да
- Скорость на малых лабиринтах: средняя
- Скорость на больших лабиринтах: медленная
- Память: высокая
- Посещённых клеток: много
**DFS:**
- Гарантия кратчайшего пути: нет
- Скорость на малых лабиринтах: быстрая
- Скорость на больших лабиринтах: быстрая
- Память: низкая
- Посещённых клеток: мало
**A*:**
- Гарантия кратчайшего пути: да (при допустимой эвристике)
- Скорость на малых лабиринтах: быстрая
- Скорость на больших лабиринтах: средняя
- Память: средняя
- Посещённых клеток: среднее
### Выводы
1. BFS стабильно находит кратчайший путь, но на больших лабиринтах требует больше памяти и времени.
2. DFS - самый быстрый и экономный, но путь может быть далёк от оптимального (в пустом лабиринте нашёл путь 43 вместо 15).
3. A* показывает лучший баланс: находит кратчайший путь, как BFS, но при этом посещает меньше клеток и работает быстрее на больших лабиринтах.
4. В лабиринте 20x20 все алгоритмы сработали быстро (0.019-0.023 мс), так как путь оказался очень коротким (5 шагов).
5. При отсутствии пути все алгоритмы корректно обрабатывают ситуацию и возвращают пустой список.
## 6. Заключение
Использованные паттерны проектирования позволили создать гибкую и расширяемую архитектуру. Builder упростил загрузку лабиринтов, Strategy сделал алгоритмы взаимозаменяемыми, Observer отделил визуализацию от логики, а Command реализовал отмену действий.
Разработанная программа успешно решает поставленную задачу. Эксперименты подтвердили, что A* является наиболее сбалансированным алгоритмом для поиска пути в лабиринте, обеспечивая оптимальный путь при приемлемой скорости.