88 lines
3.2 KiB
Python
88 lines
3.2 KiB
Python
import csv
|
|
from pathlib import Path
|
|
from typing import List, Dict, Any
|
|
|
|
from builders import TextFileMazeBuilder
|
|
from solver import MazeSolver
|
|
from strategies import BFSStrategy, DFSStrategy, AStarStrategy
|
|
|
|
|
|
class ExperimentRunner:
|
|
|
|
def __init__(self):
|
|
self.builder = TextFileMazeBuilder()
|
|
self.strategies = [
|
|
BFSStrategy(),
|
|
DFSStrategy(),
|
|
AStarStrategy()
|
|
]
|
|
|
|
def run_experiment(self, maze_file: str, runs: int = 5) -> List[Dict[str, Any]]:
|
|
|
|
try:
|
|
maze = self.builder.build_from_file(maze_file)
|
|
except ValueError as e:
|
|
# Если лабиринт некорректный (нет старта или выхода)
|
|
print(f" Пропуск: {e}")
|
|
return []
|
|
|
|
results = []
|
|
|
|
for strategy in self.strategies:
|
|
solver = MazeSolver(maze, strategy)
|
|
|
|
times = []
|
|
path_lengths = []
|
|
|
|
for _ in range(runs):
|
|
try:
|
|
path, stats = solver.solve()
|
|
times.append(stats.time_ms)
|
|
path_lengths.append(stats.path_length)
|
|
except Exception as e:
|
|
print(f" Ошибка при {strategy.name}: {e}")
|
|
continue
|
|
|
|
if times:
|
|
results.append({
|
|
'maze': Path(maze_file).stem,
|
|
'strategy': strategy.name,
|
|
'avg_time_ms': sum(times) / runs,
|
|
'min_time_ms': min(times),
|
|
'max_time_ms': max(times),
|
|
'path_length': path_lengths[0] if path_lengths else 0,
|
|
'path_found': path_lengths[0] > 0 if path_lengths else False
|
|
})
|
|
|
|
return results
|
|
|
|
def run_all_experiments(self, maze_files: List[str], runs: int = 5,
|
|
output_file: str = "results/experiment_results.csv"):
|
|
|
|
all_results = []
|
|
|
|
for maze_file in maze_files:
|
|
print(f"Запуск на лабиринте: {maze_file}")
|
|
results = self.run_experiment(maze_file, runs)
|
|
|
|
if results:
|
|
all_results.extend(results)
|
|
for r in results:
|
|
status = "✓" if r['path_found'] else "✗ (нет пути)"
|
|
print(f" {r['strategy']}: {r['avg_time_ms']:.3f} мс, путь: {r['path_length']} {status}")
|
|
else:
|
|
print(f" Лабиринт пропущен (нет старта или выхода)")
|
|
|
|
if not all_results:
|
|
print("Нет результатов для сохранения!")
|
|
return
|
|
|
|
# Сохранение в CSV
|
|
Path("results").mkdir(exist_ok=True)
|
|
with open(output_file, 'w', newline='', encoding='utf-8') as f:
|
|
writer = csv.DictWriter(f, fieldnames=all_results[0].keys())
|
|
writer.writeheader()
|
|
writer.writerows(all_results)
|
|
|
|
print(f"\nРезультаты сохранены в {output_file}")
|
|
return all_results |