2026-rff_mp/lab2/docs/report.md

7.3 KiB
Raw Blame History

Лабораторная работа 2

Поиск выхода из лабиринта

Цель работы

Цель работы состоит в реализации программы для поиска выхода из лабиринта с использованием объектно ориентированного подхода и паттернов проектирования

В программе реализована загрузка лабиринта из файла несколько алгоритмов поиска и сравнение их работы

Структура программы

В программе используются классы Cell для отдельной клетки лабиринта и Maze для самого лабиринта

Для загрузки используется MazeBuilder и его реализация TextFileMazeBuilder

Для поиска пути используется общий класс PathFindingStrategy и три алгоритма BFSStrategy DFSStrategy и AStarStrategy

За хранение результатов отвечает SearchStats а запуск поиска выполняет MazeSolver

Для вывода информации используются Observer и ConsoleView

Использованные паттерны

В работе использованы три паттерна Builder Strategy и Observer

Builder используется для загрузки лабиринта из текстового файла

TextFileMazeBuilder читает файл и создаёт объект Maze

В файле символ # обозначает стену пробел обозначает свободную клетку S является началом а E выходом

Использование Builder позволяет отдельно реализовать загрузку лабиринта и сам класс лабиринта

Strategy используется для выбора алгоритма поиска

В программе реализованы BFS DFS и A*

Все алгоритмы имеют общий интерфейс PathFindingStrategy поэтому в MazeSolver можно менять алгоритм без изменения самого решателя

Observer используется для вывода информации о поиске

MazeSolver отправляет события а ConsoleView получает их и выводит информацию в консоль

Таким образом вывод отделён от основной логики поиска

Алгоритмы поиска

BFS использует очередь и при обычных условиях находит кратчайший путь в лабиринте без весов

DFS использует стек и может найти путь быстрее но найденный путь не обязательно будет кратчайшим

A* использует очередь с приоритетом и манхэттенскую эвристику поэтому старается в первую очередь проверять клетки которые находятся ближе к выходу

Схема классов

classDiagram

class Cell { x y is_wall is_start is_exit is_passable() }

class Maze { width height cells start exit get_cell() get_neighbors() }

class MazeBuilder { build_from_file() }

class TextFileMazeBuilder { build_from_file() }

class PathFindingStrategy { find_path() }

class BFSStrategy { find_path() }

class DFSStrategy { find_path() }

class AStarStrategy { find_path() }

class SearchStats { path time_ms visited_count path_length }

class MazeSolver { maze strategy set_strategy() solve() }

class Observer { update() }

class ConsoleView { update() }

MazeBuilder <|-- TextFileMazeBuilder PathFindingStrategy <|-- BFSStrategy PathFindingStrategy <|-- DFSStrategy PathFindingStrategy <|-- AStarStrategy Observer <|-- ConsoleView MazeSolver --> Maze MazeSolver --> PathFindingStrategy MazeSolver --> Observer Maze --> Cell Тестирование

Для проверки использовалось пять разных лабиринтов

simple.txt представляет простой лабиринт dead.txt содержит тупики large.txt является большим запутанным лабиринтом empty.txt не содержит стен а в noexit.txt выход недостижим

Каждый алгоритм запускался пять раз

Во время эксперимента измерялось время поиска количество посещённых клеток и длина найденного пути

Результаты сохранялись в файл results.csv

Результаты

simple.txt Алгоритм Время мс Посещено Путь BFS 0.01464 11 6 DFS 0.01018 9 8 A* 0.01774 9 6

Все алгоритмы работают быстро

BFS и A* нашли более короткий путь чем DFS

dead.txt Алгоритм Время мс Посещено Путь BFS 0.36430 307 35 DFS 0.23494 279 151 A* 0.38374 235 35

DFS работал немного быстрее но нашёл более длинный путь

BFS и A* нашли короткий путь

large.txt Алгоритм Время мс Посещено Путь BFS 23.89446 6812 2329 DFS 84.77876 6796 4537 A* 28.69542 6791 2329

На большом лабиринте DFS показал худшее время и самый длинный путь

BFS и A* нашли одинаковый путь

empty.txt Алгоритм Время мс Посещено Путь BFS 1.277

04 1176 48 DFS 7.60228 2304 1176 A* 0.10094 48 48

В лабиринте без стен лучше всего показал себя A*

Он посетил меньше всего клеток и работал быстрее

noexit.txt Алгоритм Время мс Посещено Путь BFS 0.00370 1 0 DFS 0.00320 1 0 A* 0.00412 1 0

В этом лабиринте выход недостижим поэтому все алгоритмы быстро закончили поиск

Графики

Для сравнения времени работы были построены графики для каждого лабиринта

Графики находятся в папке docs/data

simple_time.png dead_time.png large_time.png empty_time.png и noexit_time.png

Вывод

В работе была создана программа для поиска выхода из лабиринта

Были реализованы BFS DFS и A* а также использованы паттерны Builder Strategy и Observer

По результатам эксперимента BFS хорошо подходит для поиска кратчайшего пути DFS может найти путь быстрее но он не всегда получается коротким A* хорошо показывает себя на больших и открытых лабиринтах