2026-rff_mp/maze_report.md

11 KiB
Raw Blame History

Отчёт по лабораторной работе №2

Тема: Поиск выхода из лабиринта (объектно-ориентированная реализация с паттернами)

Студент: Соколов Н.Е.
Дата: 24.05.2026


1. Цель работы

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


2. Архитектура и паттерны

2.1 Общая схема классов

Ниже представлена диаграмма классов, отражающая основные компоненты программы и связи между ними: ┌─────────────────┐ ┌─────────────────┐ │ MazeBuilder │ │ PathFinding │ │ (interface) │ │ Strategy │ └────────┬────────┘ │ (interface) │ │ └────────┬────────┘ ▼ │ ┌─────────────────┐ ┌────────┼────────┬──────────────┐ │TextFileMaze │ │ ▼ ▼ ▼ │ Builder │ │ BFSStrategy DFSStrategy AStarStrategy └────────┬────────┘ └─────────────────────────────────┘ │ ▼ ┌─────────────────────────────────────────────────────────┐ │ Maze │ ├─────────────────────────────────────────────────────────┤ │ - cells: Cell[][] │ │ - start: Cell │ │ - exit: Cell │ │ + getCell(x, y): Cell │ │ + getNeighbors(cell): List │ └─────────────────────────────────────────────────────────┘ │ ▼ ┌─────────────────┐ ┌─────────────────┐ │ MazeSolver │────▶│ SearchStats │ └─────────────────┘ └─────────────────┘ │ ▼ ┌─────────────────┐ ┌─────────────────┐ │ Observer │◀────│ ConsoleView │ │ (interface) │ └─────────────────┘ └─────────────────┘ │ ▼ ┌─────────────────┐ ┌─────────────────┐ │ Command │────▶│ MoveCommand │ │ (interface) │ └─────────────────┘ └─────────────────┘

2.2 Реализованные паттерны

Паттерн Где применён Зачем
Builder TextFileMazeBuilder Скрывает сложность создания лабиринта из файла (парсинг, валидация, установка старта/выхода). Легко добавить новый формат (JSON, бинарный) через новую реализацию MazeBuilder.
Strategy BFSStrategy, DFSStrategy, AStarStrategy Алгоритмы поиска пути можно менять на лету через setStrategy(). Новый алгоритм добавляется без изменения остального кода.
Observer ConsoleView (подписан на события MazeSolver) Отделяет отрисовку лабиринта и пути от логики поиска. Удобно заменить консольный вывод на GUI.
Command MoveCommand Позволяет пошаговое движение игрока по найденному пути, отмену ходов, макрокоманды.

3. Реализация алгоритмов поиска

3.1 BFS (поиск в ширину)

  • Использует очередь (deque).
  • Гарантирует нахождение кратчайшего пути по количеству шагов.
  • Сложность O(V + E), где V — количество клеток, E — рёбра.

3.2 DFS (поиск в глубину)

  • Использует стек (рекурсия или list).
  • Быстрый, но не гарантирует кратчайший путь.
  • Может «закопаться» вглубь, прежде чем найдет выход.

3.3 A* (звездочка)

  • Использует приоритетную очередь (heapq).
  • Эвристика: манхэттенское расстояние до выхода.
  • Компромисс между скоростью и оптимальностью: почти всегда находит кратчайший путь, но быстрее BFS на больших лабиринтах.

4. Условия эксперимента

Параметр Значение
Количество лабиринтов 4
Стратегии BFS, DFS, A*
Количество запусков на каждом лабиринте 5
Типы лабиринтов small (5×5), medium (15×15), empty (20×20), no_exit (10×10)
Инструмент замера времени time.perf_counter()
Метрики Время (мс), длина пути (клеток)

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

5.1 Время поиска пути (среднее за 5 запусков, мс)

Лабиринт BFS DFS A*
small (5×5) 0.047 0.026 0.047
medium (15×15) 0.120 0.080 0.100
empty (20×20) 1.450 0.950 1.100
no_exit (10×10) 2.300 1.800 2.100

5.2 Длина найденного пути (клеток)

Лабиринт BFS DFS A*
small 8 8 8
medium 25 32 25
empty 39 67 39
no_exit 0 0 0

5.3 Сводный график

График времени и длины пути

График сгенерирован автоматически на основе maze_results.csv.


6. Анализ результатов

6.1 BFS

  • Плюсы: всегда находит кратчайший путь.
  • Минусы: медленнее DFS на больших лабиринтах из-за необходимости обходить все клетки по слоям.
  • Вывод: лучший выбор, когда важна оптимальность пути.

6.2 DFS

  • Плюсы: самый быстрый, потребляет мало памяти.
  • Минусы: может найти очень длинный неоптимальный путь (например, в empty путь в 67 клеток вместо 39).
  • Вывод: подходит для задач, где путь может быть любым, а скорость важнее.

6.3 A*

  • Плюсы: почти идеальный компромисс: путь почти всегда кратчайший, скорость высокая.
  • Минусы: требуется хорошая эвристика (у нас — манхэттенское расстояние).
  • Вывод: рекомендуется для большинства практических задач поиска пути.

6.4 Лабиринт без выхода

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

7. Выводы

7.1 О реализации

  • Паттерны действительно сделали код гибким и расширяемым.
  • Builder изолировал загрузку — легко поменять формат файла.
  • Strategy позволил сравнивать алгоритмы без изменения MazeSolver.
  • Observer и Command добавили визуализацию и управление, не засоряя основную логику.

7.2 Рекомендации по выбору алгоритма

Сценарий Рекомендуемый алгоритм Почему
Нужен кратчайший путь BFS или A* Оба находят оптимум, A* быстрее
Скорость важнее оптимальности DFS Самый быстрый
Лабиринт с известной эвристикой A* Лучший баланс
Лабиринт без выхода BFS или A* Предсказуемое перебор всех клеток

7.3 Заключение

Лабораторная работа выполнена в полном объёме:

  • Реализованы 4 паттерна проектирования.
  • Программа загружает лабиринт из текстового файла.
  • Реализованы 3 алгоритма поиска пути.
  • Добавлена визуализация в консоли.
  • Проведены эксперименты, результаты сохранены в CSV.
  • Построены графики.
  • Оформлен отчёт.

Программа готова к использованию и легко расширяется.