8.9 KiB
Отчёт по лабораторной работе: Алгоритмы поиска пути в лабиринте
1. Цель работы
Разработка программы для загрузки лабиринта из текстового файла, реализации трёх алгоритмов поиска пути (BFS, DFS, A*) и проведения экспериментального сравнения их эффективности на лабиринтах различной сложности.
2. Структура программы
Программа написана на Python 3 и состоит из следующих основных классов:
GridPoint– представление клетки лабиринта (координаты, проходимость, флаги старта/выхода);Labyrinth– модель лабиринта (сетка клеток, методы получения соседей);TextMazeLoader– загрузка лабиринта из файла с символами#(стена),S(старт),E(выход);SearchAlgorithm(и наследникиBreadthFirst,DepthFirst,AStar) – реализация алгоритмов поиска;LabyrinthSolver– класс-оркестратор, позволяющий сменить стратегию и измеряющий время выполнения;Player,Command,MoveCommand,InteractiveView– для интерактивного режима с отменой ходов;- функции
run_experimentиgenerate_plots– для многократных запусков и построения графиков.
3. Описание алгоритмов
3.1 BFS (поиск в ширину)
Использует очередь. Гарантирует нахождение кратчайшего пути (по числу шагов). Обходит клетки в порядке увеличения расстояния от старта.
3.2 DFS (поиск в глубину)
Использует стек. Идёт «вглубь» по одному пути, не гарантирует кратчайший путь. Обычно быстрее по времени и памяти на больших лабиринтах.
3.3 A* (звездочка)
Использует приоритетную очередь и эвристику (манхэттенское расстояние). Оценивает клетку по формуле f = g + h, где g – пройденное расстояние, h – эвристика. Находит оптимальный путь, если эвристика допустима.
4. Методика эксперимента
Для каждого лабиринта каждый алгоритм запускался 3 раза, результаты усреднялись. Измерялись:
- время выполнения (в миллисекундах);
- количество посещённых клеток;
- длина найденного пути.
Тестовые лабиринты:
| Название | Размер | Описание |
|---|---|---|
| Small 10x6 | 10×6 | Простой лабиринт с извилистым коридором |
| Medium 10x10 | 10×10 | Лабиринт среднего размера с несколькими тупиками |
| Large 20x20 | 20×20 | Большой запутанный лабиринт |
| Empty 15x15 | 15×15 | Пустой лабиринт без стен (прямая линия от S до E) |
| No exit 10x10 | 10×10 | Лабиринт без буквы E (путь отсутствует) |
5. Результаты экспериментов
| Лабиринт | Алгоритм | Время, мс | Посещено клеток | Длина пути |
|---|---|---|---|---|
| Small 10x6 | BFS | 0.057 | 25 | 16 |
| Small 10x6 | DFS | 0.057 | 24 | 16 |
| Small 10x6 | A* | 0.048 | 23 | 16 |
| Medium 10x10 | BFS | 0.048 | 47 | 16 |
| Medium 10x10 | DFS | 0.035 | 44 | 30 |
| Medium 10x10 | A* | 0.098 | 47 | 16 |
| Large 20x20 | BFS | 0.099 | 100 | 36 |
| Large 20x20 | DFS | 0.070 | 75 | 68 |
| Large 20x20 | A* | 0.165 | 85 | 36 |
| Empty 15x15 | BFS | 0.133 | 133 | 17 |
| Empty 15x15 | DFS | 0.114 | 161 | 89 |
| Empty 15x15 | A* | 0.154 | 65 | 17 |
| No exit 10x10 | BFS | 0.044 | 25 | 0 |
| No exit 10x10 | DFS | 0.059 | 25 | 0 |
| No exit 10x10 | A* | 0.046 | 25 | 0 |
6. Анализ результатов
6.1. Нахождение кратчайшего пути
- BFS и A* нашли оптимальные пути во всех лабиринтах, где выход существовал (длина пути совпадает для них в каждом случае).
- DFS в лабиринтах Medium, Large и Empty дал существенно более длинные пути (30 против 16, 68 против 36, 89 против 17), что характерно для глубинного обхода без эвристики.
6.2. Время выполнения
- На малых лабиринтах все алгоритмы работают сопоставимо (0.035–0.099 мс).
- На лабиринте Large 20×20 BFS выполнился за 0.099 мс, A* – 0.165 мс (медленнее из-за сложности поддержки очереди с приоритетом), DFS – быстрее всех (0.070 мс).
- В пустом лабиринте BFS и A* обошли почти все клетки (133 и 65 посещённых соответственно), но A* за счёт эвристики посетил вдвое меньше клеток, хотя время оказалось чуть выше, чем у BFS (0.154 против 0.133 мс). Это объясняется накладными расходами на вычисление эвристики и управление кучей.
6.3. Количество посещённых клеток
- A* показал лучшую эффективность в пустом лабиринте (65 посещённых против 133 у BFS и 161 у DFS). В лабиринтах со стенами разница не столь заметна, но A* почти всегда посещал меньше клеток, чем BFS.
- DFS в среднем посещает меньше клеток, чем BFS, но при этом путь часто неоптимален.
- BFS вынужден обходить всю область равных расстояний, поэтому посещённых клеток обычно больше.
6.4. Поведение при отсутствии выхода
Все алгоритмы корректно завершились, вернув пустой путь (длина 0). В лабиринте без выхода BFS, DFS и A* посетили 25 клеток – это все доступные клетки.
7. Выводы
- BFS надёжен для поиска кратчайшего пути, но может быть медленнее на больших открытых пространствах из-за широкого обхода.
- DFS – самый быстрый по времени и экономный по памяти, но не гарантирует оптимальность пути. Его применение оправдано, когда любой путь подходит.
- A* демонстрирует лучший баланс: находит кратчайший путь и при этом посещает меньше клеток, чем BFS. Небольшое замедление на сложных лабиринтах компенсируется меньшим числом обработанных клеток.
- Программа успешно справляется с лабиринтами разного размера и конфигурации, включая отсутствие выхода.
- Интерактивный режим с отменой ходов (паттерн Command) и выбором алгоритма (паттерн Strategy) реализован и работает корректно.