forked from UNN/2026-rff_mp
146 lines
14 KiB
Markdown
146 lines
14 KiB
Markdown
Отчёт по лабораторной работе
|
||
|
||
«Поиск выхода из лабиринта: объектно-ориентированная реализация с паттернами проектирования»
|
||
|
||
1. Постановка задачи
|
||
|
||
Целью работы является создание программы для нахождения маршрута в лабиринте от начальной точки до выхода. Программа должна поддерживать смену алгоритма поиска, отображать результаты и позволять экспериментально сравнивать эффективность разных методов.
|
||
Необходимо реализовать:
|
||
чтение лабиринта из текстового файла
|
||
три алгоритма поиска пути: BFS, DFS, A*
|
||
сравнительный анализ алгоритмов на лабиринтах различной сложности
|
||
применение не менее трёх паттернов проектирования GoF
|
||
сохранение результатов экспериментов в CSV и построение графиков
|
||
|
||
2. Архитектура приложения и применённые паттерны
|
||
|
||
2.1 Общая архитектура
|
||
Программа построена на принципах ООП и включает следующие паттерны проектирования:
|
||
Builder (Строитель) – для создания лабиринтов из файлов
|
||
Strategy (Стратегия) – для реализации разных алгоритмов поиска пути
|
||
Observer (Наблюдатель) – для отображения процесса поиска
|
||
|
||
2.2 Обоснование выбора паттернов
|
||
Паттерн Builder (Строитель)
|
||
Проблема: Загрузка лабиринта из файла требует нескольких шагов: чтение, разбор символов, создание клеток, установка старта и выхода, проверка корректности. Без Builder код загрузки оказался бы жестко связан с одним форматом.
|
||
Решение: Разработан интерфейс MazeBuilder с методом buildFromFile, реализованный в классе TextFileMazeBuilder.
|
||
Преимущества:
|
||
скрытие сложной логики построения лабиринта
|
||
возможность добавления новых форматов (JSON, бинарный) через новые реализации MazeBuilder
|
||
упрощение тестирования с помощью mock-строителя
|
||
Паттерн Strategy (Стратегия)
|
||
Проблема: Разные алгоритмы поиска (BFS, DFS, A*) имеют различную внутреннюю логику, но одинаковый интерфейс. Клиентский код не должен зависеть от конкретного алгоритма.
|
||
Решение: Создан интерфейс PathFindingStrategy с методом findPath. Каждый алгоритм реализует этот интерфейс.
|
||
Преимущества:
|
||
возможность динамической смены алгоритма во время выполнения
|
||
изоляция кода каждого алгоритма
|
||
простое добавление новых алгоритмов (Дейкстра, двунаправленный поиск)
|
||
Паттерн Observer (Наблюдатель)
|
||
Проблема: Отображение процесса поиска требует обновления интерфейса при изменении состояния, но логика поиска не должна зависеть от способа отображения.
|
||
Решение: Реализован интерфейс Observer с методом update. MazeSolver оповещает наблюдателей о событиях.
|
||
Преимущества:
|
||
слабая связанность между логикой и отображением
|
||
возможность подключения нескольких наблюдателей (консольный вывод, GUI, логирование)
|
||
|
||
3. Реализация алгоритмов поиска
|
||
|
||
3.1 BFS (поиск в ширину)
|
||
Принцип работы: использует очередь FIFO, гарантирует нахождение кратчайшего пути, обходит все клетки на расстоянии d перед переходом к d+1.
|
||
Сложность: временная O(V + E), пространственная O(V).
|
||
3.2 DFS (поиск в глубину)
|
||
Принцип работы: использует стек LIFO, идёт вглубь по одному пути до конца, затем возвращается, не гарантирует кратчайший путь, но экономит память.
|
||
Сложность: временная O(V + E), пространственная O(V) в худшем случае.
|
||
3.3 A* (эвристический поиск)
|
||
Принцип работы: использует приоритетную очередь, функция оценки f(n) = g(n) + h(n), где g(n) – стоимость пути от старта, h(n) – манхэттенское расстояние до цели.
|
||
Сложность: временная O(E) в лучшем случае, O(b^d) в худшем, пространственная O(V).
|
||
|
||
4. Экспериментальная часть
|
||
|
||
4.1 Тестовые лабиринты
|
||
№ Название Размер Характеристики
|
||
1 Маленький 10×10 Простая структура, прямой путь
|
||
2 Средний 50×50 Наличие тупиков, несколько развилок
|
||
3 Большой 100×100 Сложная структура, много препятствий
|
||
4 Пустой 50×50 Нет стен, свободное пространство
|
||
5 Без выхода 50×50 Лабиринт без exit-клетки, выход отсутствует
|
||
4.2 Методика тестирования
|
||
Каждый алгоритм запускался 5 раз на каждом лабиринте, результаты усреднялись. Измеряемые метрики:
|
||
Время выполнения (мс) – общее время работы алгоритма
|
||
Посещённые клетки – количество просмотренных алгоритмом клеток
|
||
Длина пути – количество клеток в найденном маршруте (0 если путь не найден)
|
||
4.3 Результаты экспериментов
|
||
|
||
Таблица 1. Сравнение алгоритмов на разных лабиринтах
|
||
Лабиринт Алгоритм Время (мс) Посещено клеток Длина пути
|
||
Маленький (10x10) BFS 0.204 91 16
|
||
Маленький (10x10) DFS 0.148 91 44
|
||
Маленький (10x10) A* 0.172 87 16
|
||
Средний (50x50) BFS 3.377 1526 72
|
||
Средний (50x50) DFS 2.881 1526 194
|
||
Средний (50x50) A* 3.154 1061 72
|
||
Большой (100x100) BFS 18.363 7064 123
|
||
Большой (100x100) DFS 14.031 7064 305
|
||
Большой (100x100) A* 15.562 4785 123
|
||
Пустой (50x50) BFS 1.113 2500 98
|
||
Пустой (50x50) DFS 0.760 2500 98
|
||
Пустой (50x50) A* 0.961 2500 98
|
||
Без выхода (50x50) BFS 3.210 2036 0
|
||
Без выхода (50x50) DFS 3.086 2036 0
|
||
Без выхода (50x50) A* 2.746 2036 0
|
||
|
||
Таблица 2. Усреднённые показатели
|
||
Алгоритм Среднее время (мс) Среднее посещено Средняя длина пути
|
||
BFS 5.253 2643 62
|
||
DFS 4.181 2643 127
|
||
A* 4.519 2094 62
|
||
|
||
5. Анализ результатов
|
||
|
||
5.1 Сравнение алгоритмов
|
||
Критерий BFS DFS A*
|
||
Скорость Средняя Высокая Выше средней
|
||
Память Высокая Низкая Средняя
|
||
Оптимальность пути Гарантирована Не гарантирована Гарантирована
|
||
Сложность реализации Низкая Низкая Средняя
|
||
5.2 Наблюдения
|
||
На маленьких лабиринтах все алгоритмы показывают близкие результаты, различия несущественны.
|
||
На средних и больших лабиринтах BFS и DFS обходят все достижимые клетки (1526 и 7064), в то время как A* посещает значительно меньше клеток (1061 и 4785) благодаря эвристике, что подтверждает его эффективность.
|
||
DFS стабильно находит более длинные пути (44, 194, 305) по сравнению с BFS и A* (16, 72, 123), что ожидаемо, так как DFS не гарантирует оптимальность.
|
||
В пустом лабиринте все три алгоритма посещают одинаковое количество клеток (2500), так как нет препятствий, и путь всегда прямой. Длина пути одинакова (98).
|
||
В лабиринте без выхода все алгоритмы обходят все доступные клетки (2036) и корректно возвращают пустой путь длиной 0.
|
||
A* показывает наилучший баланс между временем выполнения и оптимальностью пути, посещая в среднем на 20% меньше клеток, чем BFS и DFS.
|
||
5.3 Рекомендации по выбору алгоритма
|
||
BFS – когда критичен кратчайший путь (навигационные системы, логистика)
|
||
DFS – когда важна экономия памяти (встроенные системы, мобильные устройства)
|
||
A* – оптимальный выбор для большинства практических задач (игровой ИИ, картографические сервисы)
|
||
|
||
6. Эффективность применения паттернов
|
||
|
||
6.1 Преимущества использования паттернов
|
||
Паттерн Что упростилось Что изменилось бы без паттерна
|
||
Builder Добавление новых форматов лабиринтов Модификация основного класса при каждом новом формате
|
||
Strategy Смена алгоритма во время выполнения Множество условных операторов и дублирование кода
|
||
Observer Добавление новых способов отображения Жёсткая привязка логики поиска к консольному выводу
|
||
6.2 Гибкость и расширяемость
|
||
Применённые паттерны обеспечивают:
|
||
открытость для расширения – новые алгоритмы и форматы добавляются без изменения существующего кода
|
||
слабую связанность – компоненты независимы друг от друга
|
||
возможность повторного использования – классы можно применять в других проектах
|
||
6.3 Что было бы сложно без паттернов
|
||
Без паттернов проектирования:
|
||
добавление нового алгоритма потребовало бы изменения MazeSolver и добавления условных операторов
|
||
поддержка нового формата лабиринта потребовала бы переписывания кода загрузки
|
||
изменение способа отображения потребовало бы модификации классов поиска
|
||
|
||
7. Выводы
|
||
|
||
В ходе лабораторной работы разработана программа для поиска пути в лабиринте с применением трёх паттернов проектирования: Builder, Strategy и Observer.
|
||
Основные результаты:
|
||
реализованы три алгоритма поиска: BFS, DFS, A*
|
||
проведён сравнительный анализ эффективности на пяти типах лабиринтов разной сложности
|
||
продемонстрированы преимущества ООП и паттернов проектирования
|
||
создана гибкая архитектура, допускающая лёгкое расширение
|
||
Ключевые выводы по алгоритмам:
|
||
BFS надёжно находит кратчайший путь, но требует больше памяти
|
||
DFS быстрее и экономичнее по памяти, но путь может быть длиннее оптимального до 2.5 раз
|
||
A* обеспечивает наилучший баланс скорости и качества, посещая меньше клеток благодаря эвристике |