From 163eb1010fed2aeac1fd88f93c0a2b771de2b2f2 Mon Sep 17 00:00:00 2001 From: semyanovra Date: Sun, 24 May 2026 15:10:38 +0000 Subject: [PATCH] [2] add report --- semyanovra/docs/report2.md | 177 +++++++++++++++++++++++++++++++++++++ 1 file changed, 177 insertions(+) create mode 100644 semyanovra/docs/report2.md diff --git a/semyanovra/docs/report2.md b/semyanovra/docs/report2.md new file mode 100644 index 0000000..68702a7 --- /dev/null +++ b/semyanovra/docs/report2.md @@ -0,0 +1,177 @@ +# Отчет по лабораторной работе: Поиск выхода из лабиринта + +## 1. Описание задачи + +Разработать программу для загрузки лабиринта из текстового файла, поиска пути от стартовой клетки до выхода с возможностью выбора алгоритма поиска, визуализации процесса и экспериментального сравнения эффективности алгоритмов. + +### Основные требования: +- Реализовать модель лабиринта (классы Cell, Maze) +- Реализовать загрузку лабиринта из файла с символами # (стена), S (старт), E (выход) +- Реализовать три алгоритма поиска пути: BFS, DFS, A* +- Реализовать класс-оркестратор MazeSolver с возможностью смены стратегии +- Собрать статистику: время выполнения, количество посещенных клеток, длина пути +- Провести эксперименты на лабиринтах разной сложности + +### Использованные паттерны проектирования GoF: + +#### 1. Builder +- **Где используется:** Классы `LabyrinthBuilder` и `TxtLabyrinthBuilder` +- **Почему выбран:** Создание лабиринта из файла включает сложную логику парсинга, валидации и установки старта и выхода. Builder скрывает эти детали от клиента и позволяет легко добавлять новые форматы файлов +- **Преимущества:** При добавлении нового формата достаточно создать новый класс-строитель, не меняя существующие классы Labyrinth и алгоритмы поиска + +#### 2. Strategy +- **Где используется:** Классы `SearchAlgorithm`, `BFS`, `DFS`, `AStar` +- **Почему выбран:** Алгоритмы поиска пути взаимозаменяемы и решают одну задачу разными способами. Strategy позволяет динамически менять алгоритм во время выполнения и легко добавлять новые алгоритмы +- **Преимущества:** Класс Pathfinder может использовать любую стратегию через метод set_algorithm. Добавление нового алгоритма требует только создания нового класса + +#### 3. Observer +- **Где используется:** Классы `EventListener` и `ConsoleDisplay` +- **Почему выбран:** Приложение должно обновлять консольный интерфейс при различных событиях. Observer отделяет логику отображения от логики приложения +- **Преимущества:** Легко добавить новые виды отображения без изменения основной логики + +#### 4. Command +- **Где используется:** Классы `Action` и `MoveAction` +- **Почему выбран:** Для реализации пошагового перемещения игрока с возможностью отмены действий. Command инкапсулирует действие в объект и позволяет реализовать undo и redo +- **Преимущества:** Хранение истории действий и возможность отмены последних ходов без изменения логики класса Walker + +## 2. Архитектура приложения + +Приложение состоит из следующих основных компонентов: + +| Компонент | Назначение | +|-----------|------------| +| `GridCell` | Модель клетки лабиринта (координаты, стена, старт, выход) | +| `Labyrinth` | Модель лабиринта (сетка клеток, методы доступа) | +| `TxtLabyrinthBuilder` | Загрузка лабиринта из текстового файла | +| `BFS`, `DFS`, `AStar` | Алгоритмы поиска пути | +| `Pathfinder` | Оркестратор, управляющий поиском | +| `ConsoleDisplay` | Визуализация лабиринта и игрока | +| `Walker` | Управление позицией игрока | +| `MoveAction` | Команда перемещения с поддержкой Undo | + +## 3. Реализация алгоритмов поиска пути + +### BFS (Поиск в ширину) +Алгоритм использует очередь для обхода лабиринта. Начинает со стартовой клетки, помещает её в очередь. Затем циклически извлекает клетку из начала очереди, проверяет не является ли она выходом, и добавляет всех непосещенных соседей в конец очереди. **Гарантирует нахождение кратчайшего пути** по количеству шагов. + +### DFS (Поиск в глубину) +Алгоритм использует стек для обхода лабиринта. Начинает со стартовой клетки, помещает её в стек. Затем циклически извлекает клетку из конца стека, проверяет не является ли она выходом, и добавляет всех непосещенных соседей в стек. **Не гарантирует нахождение кратчайшего пути**, но обычно быстрее по времени. + +### A* (A звездочка) +Алгоритм использует приоритетную очередь с эвристической функцией. Оценивает клетки по формуле f = g + h, где g - реальная стоимость пути от старта, h - эвристическое расстояние до выхода (манхэттенское расстояние). **Всегда находит кратчайший путь** при допустимой эвристике и обычно быстрее BFS. + +## 4. Экспериментальная часть + +### Тестовые лабиринты + +| Имя файла | Размер | Описание | +|-----------|--------|----------| +| level1.txt | 10x6 | Простой лабиринт | +| medium10x10.txt | 10x10 | Лабиринт среднего размера | +| large20x20.txt | 20x20 | Большой запутанный лабиринт | +| empty15x15.txt | 15x15 | Пустой лабиринт без стен | +| no_exit10x10.txt | 10x10 | Лабиринт без достижимого выхода | + +### Результаты замеров + +Каждый эксперимент проводился 3 раза с усреднением результатов. + +| Лабиринт | Алгоритм | Время (мс) | Посещено клеток | Длина пути | +|----------|----------|------------|-----------------|------------| +| Small 10x6 | BFS | 0.032 | 24 | 11 | +| Small 10x6 | DFS | 0.017 | 17 | 11 | +| Small 10x6 | A* | 0.064 | 24 | 11 | +| Medium 10x10 | BFS | 0.044 | 42 | 16 | +| Medium 10x10 | DFS | 0.024 | 26 | 16 | +| Medium 10x10 | A* | 0.060 | 30 | 16 | +| Large 20x20 | BFS | 0.245 | 211 | 36 | +| Large 20x20 | DFS | 0.211 | 170 | 100 | +| Large 20x20 | A* | 0.264 | 103 | 36 | +| Empty 15x15 | BFS | 0.199 | 169 | 25 | +| Empty 15x15 | DFS | 0.122 | 169 | 97 | +| Empty 15x15 | A* | 0.411 | 169 | 25 | +| No exit 10x10 | BFS | 0.054 | 45 | 18 | +| No exit 10x10 | DFS | 0.030 | 28 | 18 | +| No exit 10x10 | A* | 0.083 | 35 | 18 | + +### Графики + +![Сравнение производительности алгоритмов](maze_benchmark.png) + +На графике представлено сравнение трех алгоритмов по трем метрикам: время выполнения (мс), количество посещенных клеток и длина найденного пути. + +## 5. Анализ результатов + +### Сравнение характеристик алгоритмов + +| Характеристика | BFS | DFS | A* | +|----------------|-----|-----|-----| +| Гарантия кратчайшего пути | Да | Нет | Да | +| Скорость на малых лабиринтах | Средняя | Быстрая | Средняя | +| Скорость на больших лабиринтах | Средняя | Быстрая | Средняя | +| Потребление памяти | Высокое | Низкое | Среднее | +| Количество посещенных клеток | Много (211) | Среднее (170) | Мало (103) | + +### Детальный анализ по лабиринтам + +**Small 10x6:** +- Все алгоритмы нашли оптимальный путь длиной 11 шагов +- DFS оказался самым быстрым (0.017 мс) и посетил меньше всего клеток (17) +- A* посетил больше клеток (24), но нашел оптимальный путь + +**Medium 10x10:** +- Оптимальный путь - 16 шагов (BFS и A*) +- DFS нашел путь длиной 16 (в данном случае совпал с оптимальным) +- DFS снова самый быстрый (0.024 мс) и посетил 26 клеток против 42 у BFS + +**Large 20x20:** +- BFS и A* нашли оптимальный путь (36 шагов) +- **DFS нашел неоптимальный путь (100 шагов), что на 64 шага длиннее!** +- A* посетил значительно меньше клеток (103 против 211 у BFS) +- Это показывает преимущество эвристики A* на больших лабиринтах + +**Empty 15x15:** +- Оптимальный путь - 25 шагов (по прямой) +- DFS нашел путь длиной 97 шагов, что в 3.8 раза длиннее! +- Все алгоритмы посетили одинаковое количество клеток (169) - весь лабиринт +- A* показал самое большое время из-за накладных расходов на эвристику + +**No exit 10x10:** +- Все алгоритмы обошли весь достижимый лабиринт +- DFS посетил меньше клеток (28 против 45 у BFS) +- Длина пути 18 показывает, что алгоритмы прошли до тупика + +### Ключевые выводы + +1. **BFS** - надежный выбор, когда гарантия кратчайшего пути критична. Работает предсказуемо, но на больших лабиринтах посещает много клеток (211 против 103 у A*) + +2. **DFS** - самый быстрый алгоритм в большинстве тестов (0.017-0.211 мс), но **ненадежен для поиска оптимального пути**. В большом лабиринте путь оказался на 64% длиннее оптимального! + +3. **A*** - лучший баланс. Находит кратчайший путь (как BFS), но посещает на 51% меньше клеток в большом лабиринте. Немного медленнее DFS из-за вычисления эвристики. + +### Рекомендации по выбору алгоритма + +| Ситуация | Рекомендуемый алгоритм | Обоснование | +|----------|----------------------|-------------| +| Небольшой лабиринт (< 100 клеток) | Любой | Разница в производительности незначительна | +| Большой лабиринт, нужен кратчайший путь | **A*** | Быстрее BFS, посещает меньше клеток | +| Максимальная скорость, путь не важен | **DFS** | Самый быстрый, но может найти длинный путь | +| Лабиринт неизвестной структуры | **A*** | Лучшее соотношение скорость/качество | + +## 6. Заключение + +### Преимущества использованных паттернов + +**Builder** позволил легко реализовать загрузку лабиринтов из текстовых файлов и оставил возможность для добавления других форматов без изменения основного кода. + +**Strategy** сделал алгоритмы поиска взаимозаменяемыми. Добавление нового алгоритма (например, Дейкстры) потребовало бы только создания нового класса. + +**Observer** отделил логику отображения от логики приложения, что упростило добавление новых видов визуализации. + +**Command** позволил реализовать пошаговое управление игроком с возможностью отмены действий без усложнения класса Walker. + +### Итог + +Разработанная программа демонстрирует преимущества объектно-ориентированного подхода и использования паттернов проектирования. Код является гибким, расширяемым и легко поддерживаемым. + +Эксперименты показали, что **A*** является наиболее сбалансированным алгоритмом для поиска пути в лабиринте, обеспечивая оптимальный путь при приемлемой скорости работы и минимальном количестве посещенных клеток. DFS может быть полезен только когда скорость критична, а оптимальность пути не важна. BFS остается надежным выбором для небольших лабиринтов, где простота реализации важнее производительности. \ No newline at end of file