2026-rff_mp/konnovaea/lab2/docs/lab2_report.ipynb

238 lines
11 KiB
Plaintext
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

{
"cells": [
{
"cell_type": "markdown",
"id": "bdef001e",
"metadata": {},
"source": [
"# Отчёт \n",
"## Поиск выхода из лабиринта: применение паттернов проектирования\n",
"\n",
"**Студент:** Коннова Е.А.\n",
"**Группа:** 429\n",
"**Дата:** 22.05.2026"
]
},
{
"cell_type": "markdown",
"id": "21f948a4",
"metadata": {},
"source": [
"## Введение\n",
"\n",
"### О чём это работа\n",
"В данной работе реализуется программа для поиска выхода из лабиринта с применением паттернов проектирования. Поддерживаются три алгоритма поиска пути: BFS, DFS и A*.\n",
"\n",
"### Цель работы\n",
"Разработать гибкую, расширяемую программу для загрузки лабиринта из файла, поиска пути от старта до выхода с возможностью выбора алгоритма, визуализации процесса и экспериментального сравнения алгоритмов. Применить минимум 3 паттерна проектирования.\n",
"\n",
"### Задачи\n",
"1. Реализовать модель лабиринта (классы Cell, Maze)\n",
"2. Реализовать загрузку лабиринта из файла (паттерн Builder)\n",
"3. Реализовать алгоритмы поиска пути (паттерн Strategy): BFS, DFS, A*\n",
"4. Реализовать класс-оркестратор MazeSolver со сбором статистики\n",
"5. Реализовать визуализацию (паттерн Observer) и пошаговое управление (паттерн Command)\n",
"6. Провести эксперименты на лабиринтах разной сложности\n",
"7. Сравнить результаты и сделать выводы\n"
]
},
{
"cell_type": "markdown",
"id": "cf1dc2ba",
"metadata": {},
"source": [
"## Часть 1. Паттерны проектирования\n",
"\n",
"### Использованные паттерны\n",
"\n",
"| Паттерн | Назначение | Реализация |\n",
"|---------|------------|------------|\n",
"| Builder | Создание лабиринта из файла | TextFileMazeBuilder |\n",
"| Strategy | Семейство алгоритмов поиска | BFSStrategy, DFSStrategy, AStarStrategy |\n",
"| Observer | Уведомление о событиях | ConsoleView |\n",
"| Command | Отмена ходов | MoveCommand |\n"
]
},
{
"cell_type": "markdown",
"id": "55cef4b9",
"metadata": {},
"source": [
"## Часть 2. Реализация\n",
"\n",
"### 2.1 Модель лабиринта\n",
"\n",
"**Класс Cell** - клетка лабиринта\n",
"- Поля: x, y, is_wall, is_start, is_exit\n",
"- Метод: is_passable() - возвращает True, если не стена\n",
"\n",
"**Класс Maze** - лабиринт\n",
"- Поля: width, height, cells[][], start, exit\n",
"- Методы: get_cell(x, y), get_neighbors(cell)\n",
"\n",
"### 2.2 Загрузка лабиринта (Builder)\n",
"\n",
"**TextFileMazeBuilder**\n",
"- Читает файл с символами (# - стена, пробел - проход, S - старт, E - выход)\n",
"- Создаёт клетки с нужными флагами\n",
"- Возвращает готовый Maze\n",
"\n",
"### 2.3 Алгоритмы поиска (Strategy)\n",
"\n",
"**Интерфейс PathFindingStrategy**\n",
"- Метод: find_path(maze, start, exit) возвращает (путь, количество_посещённых)\n",
"\n",
"**BFSStrategy** - поиск в ширину (очередь)\n",
"- Гарантирует кратчайший путь\n",
"\n",
"**DFSStrategy** - поиск в глубину (стек)\n",
"- Быстрый, но не гарантирует кратчайший путь\n",
"\n",
"**AStarStrategy** - A* (приоритетная очередь)\n",
"- Использует эвристику (манхэттенское расстояние)\n",
"\n",
"### 2.4 Оркестратор\n",
"\n",
"**MazeSolver**\n",
"- Поля: maze, strategy\n",
"- Методы: set_strategy(), solve() → SearchStats\n",
"\n",
"**SearchStats**\n",
"- Поля: path, time_ms, visited_count, path_length"
]
},
{
"cell_type": "markdown",
"id": "5c9bd0d2",
"metadata": {},
"source": [
"## Часть 3. Эксперименты\n",
"\n",
"### 3.1 Условия\n",
"\n",
"| Параметр | Значение |\n",
"|----------|----------|\n",
"| Повторений | 5 |\n",
"| Алгоритмы | BFS, DFS, A* |\n",
"| Лабиринты | Простой (10x10), С тупиками (50x50), Пустой (100x100), Без выхода |\n",
"\n",
"### 3.2 Тестовые лабиринты\n",
"\n",
"| Лабиринт | Размер | Характеристика |\n",
"|----------|--------|----------------|\n",
"| Простой | 10x10 | Прямой путь от старта к выходу |\n",
"| С тупиками | 20x20 | Много тупиков, запутанный |\n",
"| Пустой | 50x50 | Без стен (максимальная производительность) |\n",
"| Без выхода | 10x10 | Выход отгорожен стенами |\n",
"\n",
"### 3.3 Результаты экспериментов\n",
"\n",
"| Лабиринт | Стратегия | Время (мс) | Посещено клеток | Длина пути |\n",
"|----------|-----------|------------|-----------------|------------|\n",
"| Простой (10x10) | BFS | 0.020 | 11 | 6 |\n",
"| Простой (10x10) | DFS | 0.012 | 9 | 8 |\n",
"| Простой (10x10) | A* | 0.020 | 9 | 6 |\n",
"| С тупиками (20x20) | BFS | 0.492 | 306 | 35 |\n",
"| С тупиками (20x20) | DFS | 0.234 | 198 | 81 |\n",
"| С тупиками (20x20) | A* | 0.456 | 225 | 35 |\n",
"| Пустой (50x50) | BFS | 3.486 | 2304 | 95 |\n",
"| Пустой (50x50) | DFS | 10.452 | 2304 | 1129 |\n",
"| Пустой (50x50) | A* | 5.743 | 2304 | 95 |\n",
"| Без выхода | BFS | 0.010 | 1 | нет пути |\n",
"| Без выхода | DFS | 0.003 | 1 | нет пути |\n",
"| Без выхода | A* | 0.004 | 1 | нет пути |\n",
"\n",
"### 3.4 Графики\n",
"\n",
"#### Простой лабиринт (10x10)\n",
"\n",
"![Время](data/simple_time_graph.png)\n",
"![Посещено](data/simple_visited_graph.png)\n",
"![Длина пути](data/simple_path_graph.png)\n",
"\n",
"#### Лабиринт с тупиками (20x20)\n",
"\n",
"![Время](data/dead_time_graph.png)\n",
"![Посещено](data/dead_visited_graph.png)\n",
"![Длина пути](data/dead_path_graph.png)\n",
"\n",
"#### Пустой лабиринт (50x50)\n",
"\n",
"![Время](data/empty_time_graph.png)\n",
"![Посещено](data/empty_visited_graph.png)\n",
"![Длина пути](data/empty_path_graph.png)\n",
"\n",
"#### Лабиринт без выхода\n",
"\n",
"![Время](data/noexit_time_graph.png)\n",
"![Посещено](data/noexit_visited_graph.png)\n",
"\n",
"### 3.5 Общая таблица результатов\n",
"\n",
"![Таблица](data/maze_table_results.png)\n",
"\n",
"### 3.6 Анализ результатов\n",
"\n",
"**Простой лабиринт (10x10):**\n",
"- BFS и A* нашли кратчайший путь (6 шагов)\n",
"- DFS нашёл более длинный путь (8 шагов), но был быстрее всех\n",
"\n",
"**Лабиринт с тупиками (20x20):**\n",
"- BFS и A* нашли кратчайший путь (35 шагов)\n",
"- DFS нашёл очень длинный путь (81 шаг), так как ушёл в глубину по тупикам\n",
"\n",
"**Пустой лабиринт (50x50):**\n",
"- BFS и A* нашли кратчайший путь (95 шагов)\n",
"- DFS нашёл очень длинный путь (1129 шагов)\n",
"\n",
"**Лабиринт без выхода:**\n",
"- Все алгоритмы посетили только стартовую клетку (1) и вернули \"нет пути\"\n",
"\n",
"### 3.7 Сравнение алгоритмов\n",
"\n",
"| Алгоритм | Кратчайший путь | Скорость | Память | Когда использовать |\n",
"|----------|-----------------|----------|--------|-------------------|\n",
"| BFS | Да | Средняя | Много | Нужен гарантированно кратчайший путь |\n",
"| DFS | Нет | Быстрая | Мало | Важна скорость, не важна длина пути |\n",
"| A* | Да | Быстрая | Средне | Большие лабиринты, есть эвристика |\n",
"\n",
"\n"
]
},
{
"cell_type": "markdown",
"id": "e687a8ee",
"metadata": {},
"source": [
"## Заключение\n",
"\n",
"### Выводы\n",
"\n",
"1. **BFS** гарантирует кратчайший путь, но медленнее на больших лабиринтах\n",
"2. **DFS** самый быстрый, но путь может быть очень длинным\n",
"3. **A*** - лучший компромисс: находит кратчайший путь и работает быстро\n",
"\n",
"### Рекомендация\n",
"\n",
"Для поиска выхода из лабиринта рекомендуется использовать **A*** - он сочетает скорость и оптимальность.\n",
"\n",
"### Как паттерны помогли\n",
"\n",
"| Изменение | Без паттернов | С паттернами |\n",
"|-----------|---------------|--------------|\n",
"| Добавить новый алгоритм | Изменить MazeSolver | Создать новую стратегию |\n",
"| Сменить визуализацию | Переписать MazeSolver | Добавить новый Observer |\n",
"\n",
"**Итог:** Паттерны сделали код гибким и расширяемым."
]
}
],
"metadata": {
"language_info": {
"name": "python"
}
},
"nbformat": 4,
"nbformat_minor": 5
}