2026-rff_mp/AgapovaDS/docs/report-2-nd.md
2026-09-02 23:35:21 +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.