diff --git a/famutdinovmd/report.md b/famutdinovmd/report.md new file mode 100644 index 0000000..a3cd5e0 --- /dev/null +++ b/famutdinovmd/report.md @@ -0,0 +1,133 @@ +# Отчёт по лабораторной работе №2 +## Поиск выхода из лабиринта +## Цель работы +Разработать гибкую, расширяемую программу для загрузки лабиринта из файла, поиска пути от старта до выхода с возможностью выбора алгоритма, визуализации процесса и экспериментального сравнения алгоритмов с применением паттернов проектирования GoF. + +```python +import sys +sys.path.append('.') + +from builders import TextFileMazeBuilder +from strategies import BFSStrategy, DFSStrategy, AStarStrategy +from solver import MazeSolver +from observers import ConsoleView +import time +import pandas as pd +import matplotlib.pyplot as plt +builder = TextFileMazeBuilder() +maze = builder.build_from_file("mazes/small.txt") +print(f"Размер лабиринта: {maze.width}×{maze.height}") +print(maze) +## Паттерн Builder (Строитель) + +```python +class TextFileMazeBuilder(MazeBuilder): + WALL_CHAR = '#' + START_CHAR = 'S' + EXIT_CHAR = 'E' + + def build_from_file(self, filename: str) -> Maze: + with open(filename, 'r') as f: + lines = f.readlines() + # парсинг и создание лабиринта + return maze + +**Ячейка 6 (паттерн Strategy):** +```markdown +## Паттерн Strategy (Стратегия) + +Реализованы три алгоритма поиска пути: +- **BFS** - поиск в ширину (гарантирует кратчайший путь) +- **DFS** - поиск в глубину (быстрый, но не оптимальный) +- **A*** - с эвристикой (манхэттенское расстояние) +strategies = { + "BFS": BFSStrategy(), + "DFS": DFSStrategy(), + "A*": AStarStrategy() +} + +results = [] + +for name, strategy in strategies.items(): + solver = MazeSolver(maze, strategy) + start_time = time.perf_counter() + path, stats = solver.solve() + end_time = time.perf_counter() + + results.append({ + "Алгоритм": name, + "Время (мс)": stats.time_ms, + "Длина пути": stats.path_length, + "Посещено клеток": stats.visited_cells + }) + + print(f"{name}: {stats}") + +df = pd.DataFrame(results) +df +## Паттерн Observer (Наблюдатель) + +```python +class ConsoleView(Observer): + def render(self, maze, path=None): + path_set = set(path) if path else set() + print("\n+" + "-" * maze.width + "+") + for y in range(maze.height): + row = [] + for x in range(maze.width): + cell = maze.get_cell(x, y) + if cell.is_start: + row.append('S') + elif cell.is_exit: + row.append('E') + elif cell in path_set: + row.append('*') + elif cell.is_wall: + row.append('#') + else: + row.append(' ') + print("|" + ''.join(row) + "|") + print("+" + "-" * maze.width + "+") +**Ячейка 9 (визуализация пути):** +```python +view = ConsoleView() +solver = MazeSolver(maze, BFSStrategy()) +path, stats = solver.solve() +view.render(maze, path=path) +print(f"Найден путь длиной {len(path)} клеток") +data = pd.read_csv("experiment_results.csv") +data +fig, axes = plt.subplots(1, 2, figsize=(12, 5)) + +algorithms = data['strategy'].unique() +mazes = data['maze_file'].unique() + +for algo in algorithms: + algo_data = data[data['strategy'] == algo] + axes[0].plot(algo_data['maze_file'], algo_data['time_mean'], marker='o', label=algo) + axes[1].plot(algo_data['maze_file'], algo_data['path_length_mean'], marker='o', label=algo) + +axes[0].set_title('Время выполнения (мс)') +axes[0].legend() +axes[1].set_title('Длина пути') +axes[1].legend() +plt.xticks(rotation=45) +plt.tight_layout() +plt.savefig('report_graphs.png') +plt.show() +## Выводы + +В ходе лабораторной работы были реализованы паттерны: + +| Паттерн | Где используется | Преимущество | +|---------|-----------------|--------------| +| **Builder** | `TextFileMazeBuilder` | Сокрытие сложности создания лабиринта | +| **Strategy** | `BFS/DFS/A*` | Легкая смена алгоритмов | +| **Observer** | `ConsoleView` | Отделение визуализации от логики | +| **Command** | `MoveCommand` | Поддержка отмены действий | + +### Сравнение алгоритмов + +- **BFS** - оптимальный по длине пути, стабильное время +- **DFS** - самый быстрый, но путь длиннее +- **A*** - баланс скорости и оптимальности