2026-rff_mp/lab2/docs/report.md

213 lines
7.3 KiB
Markdown
Raw Normal View 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* хорошо показывает себя на больших и открытых лабиринтах