9.8 KiB
Лабораторная работа: Поиск выхода из лабиринта
1. Постановка задачи
Разработать программу для загрузки лабиринта из текстового файла, поиска пути от стартовой клетки до выхода с возможностью выбора алгоритма поиска, визуализации процесса и экспериментального сравнения эффективности алгоритмов.
Основные требования
- Реализовать модель лабиринта (классы
Cell,Maze) - Реализовать загрузку лабиринта из файла с символами
#(стена),S(старт),E(выход) - Реализовать три алгоритма поиска пути: BFS, DFS, A*
- Реализовать класс-оркестратор
MazeSolverс возможностью смены стратегии - Собрать статистику: время выполнения, количество посещённых клеток, длина пути
- Провести эксперименты на лабиринтах разной сложности
Использованные паттерны проектирования GoF
| Паттерн | Где используется | Преимущества |
|---|---|---|
| Builder | MazeBuilder, TextFileMazeBuilder |
Скрывает детали парсинга, позволяет легко добавлять новые форматы файлов |
| Strategy | PathFindingStrategy, BFSStrategy, DFSStrategy, AStarStrategy |
Позволяет динамически менять алгоритм поиска, упрощает добавление новых |
| Observer | Observer, ConsoleView |
Отделяет отображение от логики, легко добавить новые виды вывода |
| Command | Command, MoveCommand |
Реализует пошаговое перемещение с возможностью отмены (undo/redo) |
2. Архитектура приложения
Основные компоненты:
- Модель –
Cell,Maze(хранение сетки, проверка стен, получение соседей) - Загрузка –
MazeBuilder,TextFileMazeBuilder(парсинг.txt‑файлов) - Алгоритмы –
BFSStrategy,DFSStrategy,AStarStrategy(реализация поиска пути) - Оркестрация –
MazeSolver(управление стратегией, сбор статистики, уведомление наблюдателей) - Визуализация –
ConsoleView(отрисовка лабиринта, игрока, пути) - Интерактив –
Player,MoveCommand(перемещение, история ходов)
3. Реализация алгоритмов поиска пути
| Алгоритм | Структура данных | Гарантия кратчайшего пути | Особенности |
|---|---|---|---|
| BFS | Очередь (deque) |
Да | Обходит лабиринт по слоям, гарантирует минимум шагов |
| DFS | Стек | Нет | Углубляется до конца, затем возвращается; экономичен по памяти |
| A* | Приоритетная очередь (heapq) + эвристика |
Да (при допустимой эвристике) | Использует манхэттенское расстояние, обычно быстрее BFS |
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.025 | 9 | 5 |
| Small 10x6 | DFS | 0.041 | 26 | 19 |
| Small 10x6 | A* | 0.015 | 5 | 5 |
| Medium 10x10 | BFS | 0.016 | 18 | 8 |
| Medium 10x10 | DFS | 0.008 | 9 | 8 |
| Medium 10x10 | A* | 0.015 | 8 | 8 |
| Large 20x20 | BFS | 0.136 | 116 | 69 |
| Large 20x20 | DFS | 0.159 | 173 | 69 |
| Large 20x20 | A* | 0.198 | 110 | 69 |
| Empty 15x15 | BFS | 0.255 | 240 | 29 |
| Empty 15x15 | DFS | 0.142 | 224 | 119 |
| Empty 15x15 | A* | 0.590 | 224 | 29 |
| No exit 10x10 | BFS | 0.042 | 36 | 0 |
| No exit 10x10 | DFS | 0.035 | 36 | 0 |
| No exit 10x10 | A* | 0.065 | 36 | 0 |
Графики
На графике представлено сравнение трёх алгоритмов по трём метрикам: время выполнения, количество посещённых клеток и длина найденного пути.
5. Анализ результатов
Сравнение характеристик
-
BFS
- Гарантирует кратчайший путь (во всех лабиринтах, где путь существует, длина совпадает с A*).
- Посещает довольно много клеток (например, 240 в пустом лабиринте).
- Время стабильно, но на больших лабиринтах уступает DFS по скорости.
-
DFS
- Самый быстрый на средних и больших лабиринтах (0.008–0.159 мс).
- Не находит кратчайший путь: в пустом лабиринте длина пути 119 вместо 29.
- Посещает среднее количество клеток (224 в пустом, 173 в большом).
-
A*
- Всегда находит оптимальный путь (как BFS).
- Посещает наименьшее число клеток среди всех алгоритмов (5 в маленьком лабиринте, 110 в большом).
- Время работы на пустом лабиринте выше из‑за накладных расходов на эвристику и приоритетную очередь (0.590 мс против 0.142 мс у DFS).
- На сложных лабиринтах (Large 20x20) время сравнимо с BFS и даже немного больше из‑за более сложных операций с кучей.
Ключевые выводы
- A показывает лучший баланс* между оптимальностью пути и количеством посещённых клеток. Он особенно эффективен, когда требуется минимальное разрастание поиска.
- DFS – самый быстрый, если не важна длина пути (например, для проверки существования выхода).
- BFS остаётся простым и предсказуемым, но уступает A* по числу посещений.
- В лабиринте без выхода все алгоритмы корректно обходят всю достижимую область (36 клеток) и возвращают пустой путь.
Рекомендации по выбору алгоритма
| Сценарий | Рекомендуемый алгоритм |
|---|---|
| Нужен гарантированно кратчайший путь и не важна скорость | BFS или A* (A* предпочтительнее) |
| Скорость критична, путь может быть неоптимальным | DFS |
| Нужен компромисс (оптимальность + мало посещений) | A* |
| Проверка существования пути (без восстановления маршрута) | DFS |
6. Заключение
Применение паттернов проектирования (Builder, Strategy, Observer, Command) позволило создать гибкую, расширяемую и легко тестируемую программу. Реализованные алгоритмы поиска пути были экспериментально сравнены на лабиринтах разной сложности. Полученные результаты подтверждают теоретические оценки: A* даёт наилучшее сочетание оптимальности и эффективности по числу посещённых клеток, DFS выигрывает по скорости, а BFS остаётся простым базовым решением.
Программа также предоставляет интерактивный режим с ручным управлением игроком и возможностью отмены ходов.
