Удалить kalinovskiymi/docs/otchet_2.md

This commit is contained in:
kalinovskiymi 2026-05-24 21:56:05 +00:00
parent 2769e3eb01
commit e5dd2683e9

View File

@ -1,146 +0,0 @@
Отчёт по лабораторной работе
«Поиск выхода из лабиринта: объектно-ориентированная реализация с паттернами проектирования»
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* обеспечивает наилучший баланс скорости и качества, посещая меньше клеток благодаря эвристике