2026-rff_mp/YaroslavtsevAS/docs/ReportLab2.md

119 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. Постановка задачи
Цель — разработать программу для загрузки лабиринта из текстового файла, поиска маршрута от старта до выхода с возможностью выбора алгоритма, визуализации процесса и экспериментального сравнения эффективности трёх классических алгоритмов поиска пути.
### Основные требования:
- Модель лабиринта: классы `Tile` (клетка) и `Labyrinth` (сетка).
- Загрузка карты из файла с символами `#` (стена), `S` (старт), `E` (выход).
- Реализация трёх стратегий поиска: BFS, DFS, A*.
- Оркестратор `LabyrinthSolver` с возможностью смены алгоритма во время выполнения.
- Сбор метрик: время работы (мс), количество посещённых клеток, длина найденного пути.
- Проведение экспериментов на пяти лабиринтах разного размера и структуры.
### Использованные паттерны проектирования
- **Builder** `TextLabyrinthBuilder` инкапсулирует логику парсинга текстового файла и создания объекта `Labyrinth`. Это упрощает добавление новых форматов.
- **Strategy** `BFS_Pathfinder`, `DFS_Pathfinder` и `AStar_Pathfinder` реализуют общий интерфейс `Pathfinder`. Класс `LabyrinthSolver` может динамически переключаться между ними.
- **Observer** интерфейс `GameObserver` и его реализация `TerminalDisplay` позволяют отделить отображение лабиринта от бизнес-логики.
- **Command** `MoveAction` оборачивает перемещение игрока, сохраняя историю и предоставляя возможность отмены (`undo`).
## 2. Архитектура приложения
- **Модель**: `Tile` (клетка) и `Labyrinth` (лабиринт).
- **Загрузка**: `LabyrinthBuilder` (абстрактный) и `TextLabyrinthBuilder`.
- **Алгоритмы**: `BFS_Pathfinder`, `DFS_Pathfinder`, `AStar_Pathfinder` — наследники `Pathfinder`.
- **Управление поиском**: `LabyrinthSolver` (смена стратегии, оповещение наблюдателей).
- **Визуализация**: `TerminalDisplay`, реализующий `GameObserver`.
- **Интерактив**: `Explorer` (игрок) и `MoveAction` (команда перемещения).
## 3. Реализация алгоритмов поиска пути
### BFS (поиск в ширину)
Использует очередь. Стартовая клетка помещается в очередь, затем на каждом шаге извлекается первый элемент. Если это выход — путь восстановлен. Иначе все непосещённые соседи добавляются в конец очереди. Гарантирует кратчайший путь по количеству шагов.
### DFS (поиск в глубину)
Вместо очереди используется стек (LIFO). Начинает со старта, на каждом шаге извлекается последний добавленный элемент. Быстрее продвигается в глубину, но путь часто оказывается далеко не оптимальным.
### A* (A-звездочка)
Применяет приоритетную очередь с эвристической функцией `f = g + h`, где `g` — реальная стоимость пути от старта, `h` — Манхэттенское расстояние до выхода. Всегда находит оптимальный путь при допустимой эвристике и обычно посещает меньше клеток.
## 4. Экспериментальная часть
### Тестовые лабиринты
| Название | Размер | Особенность |
|-------------------|-----------|------------------------------------|
| Small 10x6 | 10×6 | простой коридорный лабиринт |
| Medium 10x10 | 10×10 | средняя плотность стен |
| Large 20x20 | 20×20 | сложная запутанная структура |
| Empty 15x15 | 15×15 | полностью проходимый (без стен) |
| No exit 10x10 | 10×10 | выход заблокирован стеной |
Все эксперименты проводились с усреднением по 3 запускам для сглаживания случайных колебаний времени.
### Результаты замеров
| Лабиринт | Алгоритм | Время (мс) | Посещено клеток | Длина пути |
|------------------|----------|------------|-----------------|------------|
| Small 10x6 | BFS | 0.037 | 27 | 10 |
| Small 10x6 | DFS | 0.028 | 18 | 14 |
| Small 10x6 | A* | 0.069 | 22 | 10 |
| Medium 10x10 | BFS | 0.042 | 40 | 15 |
| Medium 10x10 | DFS | 0.017 | 21 | 15 |
| Medium 10x10 | A* | 0.058 | 28 | 15 |
| Large 20x20 | BFS | 0.091 | 64 | 31 |
| Large 20x20 | DFS | 0.054 | 64 | 41 |
| Large 20x20 | A* | 0.217 | 60 | 31 |
| Empty 15x15 | BFS | 0.380 | 223 | 25 |
| Empty 15x15 | DFS | 0.171 | 221 | 109 |
| Empty 15x15 | A* | 0.623 | 169 | 25 |
| No exit 10x10 | BFS | 0.014 | 9 | 0 |
| No exit 10x10 | DFS | 0.013 | 9 | 0 |
| No exit 10x10 | A* | 0.024 | 9 | 0 |
*Примечание: длина пути 0 означает, что маршрут не существует.*
### Визуализация
![Сравнение производительности алгоритмов](maze_performance.png)
На графиках отражены три метрики: время выполнения, число посещённых клеток и длина найденного пути.
## 5. Анализ результатов
### Сравнение алгоритмов
**BFS**
- Всегда находит кратчайший путь (длины 10, 15, 31, 25 соответственно).
- На больших и пустых лабиринтах посещает много клеток (до 223), что сказывается на времени.
- Хорошо подходит, когда оптимальность критична, а размер лабиринта умеренный.
**DFS**
- Самый быстрый по времени (0.0130.171 мс), но часто выдаёт длинные извилистые пути (14, 15, 41, 109). В пустом 15×15 путь составил 109 шагов вместо оптимальных 25.
- Число посещённых клеток невелико, что объясняет высокую скорость. Рекомендуется, когда важнее скорость, а не качество маршрута.
**A***
- Находит кратчайший путь во всех случаях (где он существует).
- Посещает в среднем меньше клеток, чем BFS (22, 28, 60, 169), что подтверждает эффективность эвристики.
- Время работы немного выше, чем у BFS, из-за накладных расходов на работу с кучей, однако разница незначительна.
### Особые случаи
- В лабиринте **No exit** все алгоритмы быстро обошли доступную область (9 клеток) и корректно вернули пустой путь.
- На **Empty 15×15** DFS показал наихудший путь (109 шагов), в то время как BFS и A* дали идеальные 25. Это наглядно демонстрирует, что DFS непригоден для задач, требующих оптимальности.
- **Large 20×20** показал близкие результаты для BFS и A* по длине пути, но DFS снова выдал более длинный маршрут (41).
### Выводы и рекомендации
- Если необходим **кратчайший путь** — выбирайте **BFS** или **A***. A* часто эффективнее по памяти, так как посещает меньше клеток.
- Если важна **максимальная скорость** и допустим неоптимальный путь — используйте **DFS**.
- **A*** является наилучшим компромиссом для большинства практических задач благодаря сбалансированному сочетанию времени и оптимальности.
## 6. Заключение
Разработанное приложение демонстрирует применение паттернов проектирования для построения гибкой и расширяемой архитектуры.
Экспериментальные данные подтверждают ожидаемое поведение алгоритмов: BFS и A* гарантируют оптимальность, DFS — высокую скорость ценой качества маршрута. A* показал наилучшее соотношение «затраты / качество», посещая меньше клеток и находя кратчайший путь.
Все полученные метрики сохранены в файл `experiment_data.csv`, графики — в `maze_performance.png`.