[2] add report
This commit is contained in:
parent
1a9317dad7
commit
163eb1010f
177
semyanovra/docs/report2.md
Normal file
177
semyanovra/docs/report2.md
Normal file
|
|
@ -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 |
|
||||
|
||||
### Графики
|
||||
|
||||

|
||||
|
||||
На графике представлено сравнение трех алгоритмов по трем метрикам: время выполнения (мс), количество посещенных клеток и длина найденного пути.
|
||||
|
||||
## 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 остается надежным выбором для небольших лабиринтов, где простота реализации важнее производительности.
|
||||
Loading…
Reference in New Issue
Block a user