forked from UNN/2026-rff_mp
отчет 2
This commit is contained in:
parent
43ea04de23
commit
8ce584051b
133
famutdinovmd/report.md
Normal file
133
famutdinovmd/report.md
Normal file
|
|
@ -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*** - баланс скорости и оптимальности
|
||||||
Loading…
Reference in New Issue
Block a user