2026-rff_mp/famutdinovmd/experiments.py

100 lines
3.9 KiB
Python
Raw Normal View History

import csv
import time
from typing import List, Dict
from models import Maze
from builders import TextFileMazeBuilder
from strategies import BFSStrategy, DFSStrategy, AStarStrategy
from solver import MazeSolver
def run_experiment(maze: Maze, strategy_name: str, strategy, repeats: int = 5) -> Dict:
"""Запускает эксперимент для одной стратегии"""
times = []
visited_counts = []
path_lengths = []
path_found = True
for _ in range(repeats):
solver = MazeSolver(maze, strategy)
path, stats = solver.solve()
times.append(stats.time_ms)
visited_counts.append(stats.visited_cells)
path_lengths.append(stats.path_length)
path_found = stats.path_found
return {
'strategy': strategy_name,
'time_mean': sum(times) / len(times),
'time_min': min(times),
'time_max': max(times),
'visited_mean': sum(visited_counts) / len(visited_counts),
'path_length_mean': sum(path_lengths) / len(path_lengths) if path_found else 0,
'path_found': path_found
}
def run_all_experiments(maze_files: List[str], repeats: int = 5) -> List[Dict]:
"""Запускает эксперименты для всех лабиринтов и стратегий"""
builder = TextFileMazeBuilder()
strategies = [
('BFS', BFSStrategy()),
('DFS', DFSStrategy()),
('A*', AStarStrategy())
]
results = []
for maze_file in maze_files:
try:
maze = builder.build_from_file(maze_file)
except (ValueError, FileNotFoundError) as e:
print(f"❌ Ошибка: {e}")
continue
print(f"\n📊 Лабиринт: {maze_file}")
print(f" Размер: {maze.width}×{maze.height}")
print(f" Старт: ({maze.start.x}, {maze.start.y})")
print(f" Выход: ({maze.exit.x}, {maze.exit.y})")
for strategy_name, strategy in strategies:
print(f" 🧪 Тестирование: {strategy_name}")
result = run_experiment(maze, strategy_name, strategy, repeats)
result['maze_file'] = maze_file.split('/')[-1]
result['maze_size'] = f"{maze.width}×{maze.height}"
results.append(result)
status = "" if result['path_found'] else ""
print(f" {status} Время: {result['time_mean']:.2f} мс, "
f"Посещено: {result['visited_mean']:.0f}, "
f"Путь: {result['path_length_mean']:.0f}")
return results
def save_results_to_csv(results: List[Dict], filename: str = "experiment_results.csv") -> None:
"""Сохраняет результаты в CSV файл"""
with open(filename, 'w', newline='', encoding='utf-8') as f:
writer = csv.DictWriter(f, fieldnames=[
'maze_file', 'maze_size', 'strategy',
'time_mean', 'time_min', 'time_max',
'visited_mean', 'path_length_mean', 'path_found'
])
writer.writeheader()
writer.writerows(results)
print(f"\n💾 Результаты сохранены в {filename}")
def print_results_table(results: List[Dict]) -> None:
"""Выводит результаты в виде таблицы"""
print("\n" + "=" * 80)
print("РЕЗУЛЬТАТЫ ЭКСПЕРИМЕНТОВ")
print("=" * 80)
for res in results:
print(f"\n📁 Лабиринт: {res['maze_file']}")
print(f" 📐 Размер: {res['maze_size']}")
print(f" 🎯 Стратегия: {res['strategy']}")
print(f" ⏱️ Время (ср): {res['time_mean']:.2f} мс")
print(f" 📍 Посещено: {res['visited_mean']:.0f} клеток")
print(f" 🛤️ Длина пути: {res['path_length_mean']:.0f}")