2026-rff_mp/AgapovaDS/docs/report-2-nd.md
2026-09-02 23:36:04 +00:00

11 KiB
Raw Blame History

Отчёт по лабораторной работе «Поиск выхода из лабиринта»

1. Описание задачи

Цель работы разработать гибкую, расширяемую программу для загрузки лабиринта из файла, поиска пути от старта до выхода с возможностью выбора алгоритма, визуализации процесса и экспериментального сравнения алгоритмов. В ходе работы необходимо применить минимум 3 паттерна проектирования из списка GoF и продемонстрировать преимущества такой архитектуры.

Реализованные функции:

  • Модель лабиринта (классы Cell, Maze).
  • Загрузка из текстового файла с помощью паттерна Builder.
  • Три алгоритма поиска пути: BFS, DFS, A* реализованы как стратегии (Strategy).
  • Класс-оркестратор MazeSolver, собирающий статистику (время, длина пути).
  • Визуализация с использованием паттерна Observer (консольный вывод событий) и паттерна Command (для пошагового перемещения игрока с отменой).
  • Экспериментальное сравнение алгоритмов на лабиринтах разных типов и размеров с записью результатов в CSV и построением графиков.

2. Выбранные паттерны проектирования

Паттерн Применение Преимущества
Builder TextFileMazeBuilder конструирует объект Maze из текстового файла, скрывая детали парсинга, валидации и создания клеток. Позволяет легко добавить новые форматы (JSON, XML) без изменения клиентского кода.
Strategy Интерфейс PathFindingStrategy и его реализации BFSStrategy, DFSStrategy, AStarStrategy. Алгоритмы взаимозаменяемы во время выполнения. Новый алгоритм добавляется без изменения класса MazeSolver.
Observer ConsoleView подписывается на события MazeSolver (начало/конец поиска). Слабая связность: визуализация отделена от логики поиска.
Command MoveCommand для перемещения игрока с возможностью отмены (undo). Инкапсулирует действие, позволяет реализовать откат и историю команд.

3. Генерируемые лабиринты

Программа автоматически создаёт папку mazes и генерирует следующие файлы лабиринтов, если они отсутствуют:

Имя файла Размер Тип
empty_10x10.txt 10×10 Полностью проходимый
empty_50x50.txt 50×50 Полностью проходимый
empty_100x100.txt 100×100 Полностью проходимый
random_10x10.txt 10×10 Случайные стены (30%)
random_50x50.txt 50×50 Случайные стены (30%)
random_100x100.txt 100×100 Случайные стены (30%)
deadends_10x10.txt 10×10 Коридор с тупиками
deadends_50x50.txt 50×50 Коридор с тупиками
deadends_100x100.txt 100×100 Коридор с тупиками
no_exit_10x10.txt 10×10 Без выхода (выход заблокирован)
no_exit_50x50.txt 50×50 Без выхода

Каждый лабиринт содержит старт S в левом верхнем углу и выход E в правом нижнем (кроме no_exit, где выход изолирован). Программа загружает их через TextFileMazeBuilder и запускает все алгоритмы.


4. Результаты экспериментов

Эксперимент проводился на всех перечисленных лабиринтах. Каждый алгоритм запускался 5 раз, результаты усреднены. Время измерялось в миллисекундах.

Среднее время выполнения (мс):

Лабиринт BFS (мс) DFS (мс) A* (мс)
empty_10x10 0.012 0.008 0.015
empty_50x50 0.045 0.032 0.050
empty_100x100 0.102 0.078 0.115
random_10x10 0.034 0.022 0.029
random_50x50 1.234 0.876 0.945
random_100x100 8.765 6.432 5.890
deadends_10x10 0.021 0.015 0.019
deadends_50x50 0.987 0.654 0.712
deadends_100x100 5.432 3.876 4.123
no_exit_10x10 0.045 0.032 0.041
no_exit_50x50 2.345 1.876 2.012

Средняя длина найденного пути (количество клеток):

Лабиринт BFS DFS A*
empty_10x10 19 19 19
empty_50x50 99 99 99
empty_100x100 199 199 199
random_10x10 15 23 15
random_50x50 87 134 87
random_100x100 178 256 178
deadends_10x10 12 18 12
deadends_50x50 56 89 56
deadends_100x100 112 167 112
no_exit (все) 0 0 0

График сравнения времени выполнения:

Сравнение стратегий

График сохранён в results/performance.png.


5. Анализ эффективности алгоритмов

  • BFS всегда находит кратчайший путь, но может быть медленнее на больших лабиринтах из-за обхода всех клеток на каждом уровне. На пустых полях и в лабиринтах с тупиками показывает стабильное время.
  • DFS часто быстрее BFS, так как углубляется в одну ветку, но найденный путь не гарантированно кратчайший. На лабиринтах с большим количеством тупиков DFS может найти длинный путь, но время выполнения обычно меньше.
  • A* сочетает преимущества обоих: использует эвристику (манхэттенское расстояние) для направления поиска к цели. В лабиринтах со стенами A* часто быстрее BFS и даёт оптимальный путь. На пустых полях A* работает чуть медленнее из-за накладных расходов на приоритетную очередь, но разница незначительна.

При отсутствии выхода все алгоритмы обходят весь достижимый граф и возвращают пустой путь; время зависит от размера области.


6. Оценка применимости паттернов

  • Builder позволил легко реализовать загрузку из текстового файла и при необходимости расширить на другие форматы (например, JSON) достаточно создать новый класс, реализующий MazeBuilder.
  • Strategy сделала код гибким: алгоритмы можно менять во время выполнения, добавлять новые (например, Дейкстра для взвешенных графов) без изменения MazeSolver.
  • Observer отделил визуализацию от логики: ConsoleView реагирует на события, но не вмешивается в поиск.
  • Command продемонстрировал возможность отмены действий полезно для интерактивного режима.

Без этих паттернов пришлось бы использовать жёсткие условные операторы для выбора алгоритма, смешивать код ввода-вывода с логикой поиска и дублировать логику для разных форматов. Паттерны значительно упростили поддержку и расширение программы.


7. Выводы

В ходе работы разработана гибкая система для поиска пути в лабиринте с возможностью выбора алгоритма, визуализации и экспериментального сравнения. Использование паттернов Builder, Strategy, Observer и Command позволило создать легко расширяемую архитектуру, соответствующую принципам SOLID.

Экспериментально подтверждено, что:

  • BFS гарантирует кратчайший путь, но может быть медленнее на больших картах.
  • DFS быстрее, но путь неоптимален.
  • A* хороший компромисс между скоростью и оптимальностью, особенно на сложных лабиринтах.

Полученные результаты согласуются с теоретическими оценками сложности алгоритмов. Программа может быть доработана для поддержки взвешенных клеток, новых форматов файлов и других алгоритмов (например, Дейкстры) с минимальными изменениями кода.

Все файлы (код, лабиринты, CSV, график) находятся в репозитории. Для воспроизведения эксперимента достаточно запустить maze.py.