forked from UNN/2026-rff_mp
added report
This commit is contained in:
parent
9c6804eea8
commit
10dcc4307f
BIN
soninrv/docs/performance_plot.png
Normal file
BIN
soninrv/docs/performance_plot.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 84 KiB |
105
soninrv/docs/report2.md
Normal file
105
soninrv/docs/report2.md
Normal file
|
|
@ -0,0 +1,105 @@
|
|||
# Отчёт по лабораторной работе «Поиск выхода из лабиринта»
|
||||
|
||||
## 1. Цель работы
|
||||
|
||||
Разработать гибкую расширяемую программу для загрузки лабиринта из текстового файла, поиска пути от старта до выхода с возможностью выбора алгоритма и экспериментального сравнения алгоритмов. В ходе работы применены паттерны проектирования GoF: **Builder**, **Strategy**, **Observer**, **Command**.
|
||||
|
||||
Реализованные алгоритмы поиска пути:
|
||||
|
||||
- **BFS** (поиск в ширину) — гарантирует кратчайший путь по числу шагов.
|
||||
- **DFS** (поиск в глубину) — не гарантирует кратчайший путь, но быстрее при удачном порядке соседей.
|
||||
- **A\*** (с манхэттенской эвристикой) — направленный поиск, учитывает веса клеток.
|
||||
- **Dijkstra** — оптимален для взвешенных графов, без эвристики.
|
||||
|
||||
Тестовые лабиринты:
|
||||
|
||||
- Маленький 10×10 — простой путь.
|
||||
- Средний 50×50 — с тупиками (алгоритм Прима).
|
||||
- Большой 100×100 — запутанная структура.
|
||||
- Пустой 30×30 — без стен, демонстрирует максимальную нагрузку.
|
||||
- Без выхода 20×20 — старт и выход разделены глухой стеной.
|
||||
- Взвешенный 40×40 — клетки с разным весом: асфальт (1), песок (2), болото (3).
|
||||
|
||||
Каждый эксперимент повторялся 7 раз, результаты усреднены.
|
||||
|
||||
## 2. Описание паттернов
|
||||
|
||||
| Паттерн | Классы | Назначение |
|
||||
|---|---|---|
|
||||
| Builder | `MazeBuilder`, `TextFileMazeBuilder` | Скрывает парсинг файла; новый формат = новый класс |
|
||||
| Strategy | `PathFindingStrategy`, BFS/DFS/A\*/Dijkstra | Смена алгоритма одной строкой без изменения остального кода |
|
||||
| Observer | `Observer`, `ConsoleView` | Визуализация отделена от логики поиска |
|
||||
| Command | `Command`, `MoveCommand`, `CommandHistory` | Пошаговое управление игроком с поддержкой undo |
|
||||
|
||||
## 3. Результаты экспериментов
|
||||
|
||||
Усреднённые значения (7 повторений) представлены в таблице:
|
||||
|
||||
| Лабиринт | Алгоритм | Время, мс | Посещено клеток | Длина пути |
|
||||
|---|---|---|---|---|
|
||||
| 10×10 | BFS | 0.081 | 28 | 21 |
|
||||
| 10×10 | DFS | 0.053 | 22 | 21 |
|
||||
| 10×10 | A\* | 0.088 | 24 | 21 |
|
||||
| 10×10 | Dijkstra | 0.672 | 28 | 21 |
|
||||
| 50×50 | BFS | 1.150 | 493 | 257 |
|
||||
| 50×50 | DFS | 0.614 | 263 | 257 |
|
||||
| 50×50 | A\* | 1.220 | 357 | 257 |
|
||||
| 50×50 | Dijkstra | 1.685 | 493 | 257 |
|
||||
| 100×100 | BFS | 11.378 | 4783 | 1953 |
|
||||
| 100×100 | DFS | 5.141 | 2161 | 1953 |
|
||||
| 100×100 | A\* | 18.019 | 4741 | 1953 |
|
||||
| 100×100 | Dijkstra | 17.489 | 4783 | 1953 |
|
||||
| 30×30 пустой | BFS | 1.832 | 784 | 55 |
|
||||
| 30×30 пустой | DFS | 1.151 | 433 | 379 |
|
||||
| 30×30 пустой | A\* | 3.748 | 784 | 55 |
|
||||
| 30×30 пустой | Dijkstra | 3.945 | 784 | 55 |
|
||||
| 20×20 без выхода | BFS | 0.370 | 162 | — |
|
||||
| 20×20 без выхода | DFS | 0.373 | 162 | — |
|
||||
| 20×20 без выхода | A\* | 0.708 | 162 | — |
|
||||
| 20×20 без выхода | Dijkstra | 0.677 | 162 | — |
|
||||
| 40×40 взвешенный | BFS | 1.104 | 533 | 321 |
|
||||
| 40×40 взвешенный | DFS | 0.774 | 361 | 321 |
|
||||
| 40×40 взвешенный | A\* | 1.516 | 452 | 321 |
|
||||
| 40×40 взвешенный | Dijkstra | 1.725 | 533 | 321 |
|
||||
|
||||
Графическое представление результатов приведено на рисунке ниже.
|
||||
|
||||

|
||||
|
||||
## 4. Анализ результатов
|
||||
|
||||
### 4.1. BFS
|
||||
|
||||
Гарантирует кратчайший путь по числу шагов. Исследует все клетки на расстоянии d перед переходом к d+1, поэтому число посещённых клеток максимально среди всех алгоритмов — на лабиринте 100×100 это 4783 клетки. На пустом лабиринте 30×30 BFS находит оптимальный путь длиной 55 клеток, тогда как DFS даёт 379. Время растёт линейно с размером: от 0.08 мс (10×10) до 11.4 мс (100×100).
|
||||
|
||||
### 4.2. DFS
|
||||
|
||||
Самый быстрый алгоритм по времени: на лабиринте 100×100 — 5.1 мс против 11.4 мс у BFS. Посещает вдвое меньше клеток (2161 против 4783), так как уходит глубоко в одном направлении. Однако на пустом лабиринте DFS даёт путь в 7 раз длиннее оптимального (379 против 55) — алгоритм уходит в угол и обходит весь лабиринт по периметру. Оптимальная длина пути при этом совпадает с BFS только в лабиринтах-лабиринтах (50×50 и 100×100), где единственный путь — сам.
|
||||
|
||||
### 4.3. A\*
|
||||
|
||||
На невзвешенных лабиринтах находит тот же кратчайший путь, что BFS, но исследует на 20–30% меньше клеток благодаря манхэттенской эвристике (на 50×50: 357 против 493). Однако на большом лабиринте 100×100 оказывается медленнее BFS (18 мс против 11 мс) из-за накладных расходов на `heapq`. На взвешенном лабиринте A\* корректно учитывает стоимость клеток, в отличие от BFS.
|
||||
|
||||
### 4.4. Dijkstra
|
||||
|
||||
На невзвешенных лабиринтах полностью совпадает с BFS по посещённым клеткам и длине пути, но медленнее из-за `heapq` вместо `deque`. На взвешенном лабиринте 40×40 корректно минимизирует суммарный вес пути. Практически вытесняется A\* везде, где цель заранее известна.
|
||||
|
||||
### 4.5. Лабиринт «без выхода»
|
||||
|
||||
Все алгоритмы обходят все 162 доступные клетки левой секции и возвращают пустой путь. Реализация корректно обрабатывает этот случай через событие `no_path` для Observer. A\* и Dijkstra работают медленнее (0.7 мс против 0.37 мс у BFS/DFS) из-за накладных расходов `heapq` при полном обходе без нахождения цели.
|
||||
|
||||
## 5. Выводы и рекомендации
|
||||
|
||||
На основе полученных результатов можно сформулировать следующие рекомендации:
|
||||
|
||||
- **Кратчайший путь в невзвешенном лабиринте → BFS.** Гарантированный результат, простая реализация на `deque`, линейное масштабирование.
|
||||
|
||||
- **Максимальная скорость, длина пути не критична → DFS.** В 2 раза быстрее BFS на больших лабиринтах, посещает вдвое меньше клеток. Не использовать на открытых пространствах — путь может быть многократно длиннее оптимального.
|
||||
|
||||
- **Взвешенный граф, цель известна → A\*.** Направленный поиск + учёт весов. На небольших и средних лабиринтах быстрее и экономнее BFS. На очень больших (100×100+) накладные расходы `heapq` могут перевесить выигрыш от эвристики.
|
||||
|
||||
- **Взвешенный граф, нужны все кратчайшие расстояния → Dijkstra.** Оптимален без целевой точки. С целевой точкой предпочтительнее A\*.
|
||||
|
||||
**Итог:** для навигации в лабиринте с одним выходом оптимален BFS (гарантия) или DFS (скорость). A\* предпочтителен при взвешенных клетках. Паттерн Strategy позволяет переключать алгоритмы без изменения остального кода — `solver.set_strategy(AStarStrategy())`.
|
||||
|
||||
|
||||
Loading…
Reference in New Issue
Block a user