2026-rff_mp/famutdinovmd/report.md
2026-05-25 02:42:13 +03:00

134 lines
4.9 KiB
Markdown
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.

# Отчёт по лабораторной работе №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*** - баланс скорости и оптимальности