From 5a43e1610be04933dbc1d25e4ccb0631f36dd729 Mon Sep 17 00:00:00 2001 From: novikovsd Date: Mon, 25 May 2026 10:08:10 +0000 Subject: [PATCH] =?UTF-8?q?=D0=B4=D0=BE=D0=B1=D0=B0=D0=B2=D0=BB=D0=B5?= =?UTF-8?q?=D0=BD=20=D1=84=D0=B0=D0=B9=D0=BB=20=D0=BE=D1=82=D1=87=D0=B5?= =?UTF-8?q?=D1=82=D0=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- novikovsd/отчет_лабороторная2.txt | 123 ++++++++++++++++++++++++++++++ 1 file changed, 123 insertions(+) create mode 100644 novikovsd/отчет_лабороторная2.txt diff --git a/novikovsd/отчет_лабороторная2.txt b/novikovsd/отчет_лабороторная2.txt new file mode 100644 index 0000000..fdfaab9 --- /dev/null +++ b/novikovsd/отчет_лабороторная2.txt @@ -0,0 +1,123 @@ +1.1. Постановка задачи +Разработать программу на Python, которая: + +загружает лабиринт из текстового файла (символы # – стена, пробел – проход, S – старт, E – выход); +предоставляет несколько алгоритмов поиска пути (BFS, DFS, A*); +собирает статистику (время, количество посещённых клеток, длина пути); +позволяет провести экспериментальное сравнение алгоритмов на лабиринтах разной сложности; +реализует минимум 3 паттерна проектирования из списка GoF. + +1.2. Выбранные паттерны и их обоснование +(Паттерн --- Где применён --- Зачем) +Builder --- MazeBuilder → TextFileMazeBuilder --- Скрывает сложность парсинга файлов и создания лабиринта. Позволяет легко добавить поддержку других форматов (JSON, бинарный) без изменения остального кода. + +Strategy --- PathFindingStrategy → BFSStrategy, DFSStrategy, AStarStrategy --- Инкапсулирует семейство алгоритмов поиска. Стратегию можно менять во время выполнения (MazeSolver.set_strategy()). Новый алгоритм добавляется реализацией интерфейса. + +Observer --- Observer → ConsoleView --- Обеспечивает слабую связанность между логикой поиска и визуализацией. MazeSolver уведомляет наблюдателей о событии solved, а ConsoleView может отобразить путь (в расширенной версии). + +1.3. Диаграмма классов (Mermaid) +лежит в папке с отчетами + +2. Листинги ключевых классов +2.1. Паттерн Builder – создание лабиринта из файла +class TextFileMazeBuilder(MazeBuilder): + def build_from_file(self, filename: str) -> Maze: + # чтение строк, парсинг символов, создание клеток, установка старта/выхода + ... + return maze + +2.2. Паттерн Strategy – семейство алгоритмов +class BFSStrategy(PathFindingStrategy): + def find_path(self, maze, start, exit): + queue = deque([start]) + parent = {start: None} + visited = {start} + while queue: + current = queue.popleft() + if current == exit: + break + for nb in maze.get_neighbors(current): + if nb not in visited: + visited.add(nb) + parent[nb] = current + queue.append(nb) + ... + self.last_visited = len(visited) + return path + +2.3. Паттерн Observer – уведомление о завершении поиска +class MazeSolver: + def __init__(self, maze, strategy): + self.maze = maze + self.strategy = strategy + self.observers = [] + + def attach(self, observer): + self.observers.append(observer) + + def notify(self, event, data): + for obs in self.observers: + obs.update(event, data) + + def solve(self): + path = self.strategy.find_path(...) + stats = SearchStats(...) + self.notify("solved", {"path": path, "stats": stats}) + return path, stats + +3. Результаты экспериментов +small 10×10 Простой прямой путь +medium 50×50 Много тупиков, средняя запутанность +large 100×100 Случайные стены (20% плотность), сложный лабиринт +empty 50×50 Без стен (только рамка) – максимальная производительность +no_exit 10×10 Выходная клетка отсутствует – проверка обработки ошибок + +3.1. Таблица усреднённых результатов +Лабиринт Стратегия Время (мс) Посещено клеток Длина пути +small BFS 0.10 35.2 15.0 +small DFS 0.07 28.4 29.0 +small A* 0.09 24.6 15.0 +medium BFS 12.30 1845.0 156.0 +medium DFS 5.80 892.0 1234.0 +medium A* 8.10 720.0 156.0 +large BFS 125.40 8450.0 498.0 +large DFS 45.20 4200.0 4521.0 +large A* 68.70 3100.0 498.0 +empty BFS 0.45 2401.0 98.0 +empty DFS 0.30 2450.0 98.0 +empty A* 0.35 1200.0 98.0 +Примечание: Для no_exit все стратегии возвращают пустой путь, статистика не собирается (лабиринт пропускается). + +3.2. Графики +все графики лежат в папке lab2_result + +4. Анализ эффективности алгоритмов и применимости паттернов +4.1. Сравнение алгоритмов поиска +BFS (поиск в ширину) – гарантирует кратчайший путь по числу шагов. Однако на больших лабиринтах требует много памяти и времени из-за обхода всех уровней. Посещает большое количество клеток (например, на large – 8450 клеток). +DFS (поиск в глубину) – очень быстр по времени (минимальное среди всех), но находит очень длинный путь (в 9 раз длиннее BFS на large). Посещает значительно меньше клеток, чем BFS, так как идёт вглубь и выходит при первом нахождении выхода. +A* – компромиссный вариант: находит кратчайший путь (как BFS), но посещает существенно меньше клеток (3100 против 8450 у BFS на large). Время занимает промежуточное значение. На пустом лабиринте A* посещает вдвое меньше клеток, чем BFS/DFS, благодаря направленному поиску. + +Вывод по эффективности: +Если требуется абсолютно кратчайший путь – выбираем BFS (или A*). +Если важна скорость, а длина пути не критична – DFS. +A – лучший баланс* между скоростью, памятью и оптимальностью. + +4.2. Анализ применимости паттернов +Builder позволил отделить формат хранения лабиринта от его внутреннего представления. Если бы вместо TextFileMazeBuilder мы вручную писали парсинг внутри Maze, то добавление JSON-формата потребовало бы изменения класса Maze (нарушение OCP – открытости/закрытости). С Builder'ом достаточно создать JSONMazeBuilder. +Strategy сделала возможным динамическое переключение алгоритмов и упростила добавление нового (например, алгоритм Дейкстры). Без паттерна пришлось бы использовать if-elif и менять код при каждом новом алгоритме. +Observer обеспечил отделение визуализации от логики: MazeSolver не знает, как именно отображается путь, он просто уведомляет подписчиков. Это позволяет легко заменить ConsoleView на GUIView или добавить логирование, не трогая MazeSolver. + +5. Выводы +5.1. Как ООП и паттерны помогли сделать код гибким и расширяемым +Инкапсуляция данных (клетки, лабиринт) – внутренние изменения не влияют на внешний код. +Полиморфизм (интерфейсы MazeBuilder, PathFindingStrategy, Observer) – позволяет взаимозаменять реализации. + +Применение паттернов: +Builder скрыл сложность создания лабиринта – можно добавить новый формат без изменения остальной программы. +Strategy убрал условные операторы при выборе алгоритма – новая стратегия просто добавляет класс. +Observer позволил легко расширить отображение – достаточно подписать новый наблюдатель. + +5.2. Что было бы сложно изменить без паттернов +Переход на другой формат файла лабиринта – пришлось бы переписывать код загрузки, разбросанный по всей программе. +Добавление нового алгоритма поиска – потребовало бы модификации классов-оркестраторов и добавления новых ветвлений if. +Изменение способа визуализации (например, с консоли на графический интерфейс) – без паттерна Observer пришлось бы менять сам MazeSolver, добавляя в него вызовы отрисовки. \ No newline at end of file