forked from UNN/2026-rff_mp
144 lines
3.3 KiB
Python
144 lines
3.3 KiB
Python
|
|
import csv
|
||
|
|
import os
|
||
|
|
|
||
|
|
from builders import TextFileMazeBuilder
|
||
|
|
|
||
|
|
from solver import MazeSolver
|
||
|
|
|
||
|
|
from strategies import (
|
||
|
|
BFSStrategy,
|
||
|
|
DFSStrategy,
|
||
|
|
AStarStrategy
|
||
|
|
)
|
||
|
|
|
||
|
|
|
||
|
|
# =========================================================
|
||
|
|
# Benchmark
|
||
|
|
# =========================================================
|
||
|
|
|
||
|
|
class BenchmarkRunner:
|
||
|
|
|
||
|
|
def __init__(self):
|
||
|
|
|
||
|
|
self.strategies = [
|
||
|
|
("BFS", BFSStrategy()),
|
||
|
|
("DFS", DFSStrategy()),
|
||
|
|
("A*", AStarStrategy()),
|
||
|
|
]
|
||
|
|
|
||
|
|
# =====================================================
|
||
|
|
# Run benchmark
|
||
|
|
# =====================================================
|
||
|
|
|
||
|
|
def run(
|
||
|
|
self,
|
||
|
|
maze_files: list[str],
|
||
|
|
runs_per_test: int = 5
|
||
|
|
):
|
||
|
|
|
||
|
|
results = []
|
||
|
|
|
||
|
|
builder = TextFileMazeBuilder()
|
||
|
|
|
||
|
|
for maze_file in maze_files:
|
||
|
|
|
||
|
|
print()
|
||
|
|
print(f"Testing: {maze_file}")
|
||
|
|
|
||
|
|
maze = builder.build_from_file(
|
||
|
|
maze_file
|
||
|
|
)
|
||
|
|
|
||
|
|
for strategy_name, strategy in self.strategies:
|
||
|
|
|
||
|
|
total_time = 0
|
||
|
|
total_visited = 0
|
||
|
|
total_path_length = 0
|
||
|
|
|
||
|
|
for _ in range(runs_per_test):
|
||
|
|
|
||
|
|
solver = MazeSolver(
|
||
|
|
maze,
|
||
|
|
strategy
|
||
|
|
)
|
||
|
|
|
||
|
|
path, stats = solver.solve()
|
||
|
|
|
||
|
|
total_time += stats.time_ms
|
||
|
|
total_visited += stats.visited_cells
|
||
|
|
total_path_length += stats.path_length
|
||
|
|
|
||
|
|
avg_time = (
|
||
|
|
total_time / runs_per_test
|
||
|
|
)
|
||
|
|
|
||
|
|
avg_visited = (
|
||
|
|
total_visited / runs_per_test
|
||
|
|
)
|
||
|
|
|
||
|
|
avg_path_length = (
|
||
|
|
total_path_length / runs_per_test
|
||
|
|
)
|
||
|
|
|
||
|
|
result = {
|
||
|
|
"maze": maze_file,
|
||
|
|
"strategy": strategy_name,
|
||
|
|
"time_ms": round(avg_time, 3),
|
||
|
|
"visited_cells": int(avg_visited),
|
||
|
|
"path_length": int(avg_path_length),
|
||
|
|
}
|
||
|
|
|
||
|
|
results.append(result)
|
||
|
|
|
||
|
|
print(
|
||
|
|
f"{strategy_name}: "
|
||
|
|
f"time={avg_time:.3f} ms, "
|
||
|
|
f"visited={avg_visited:.0f}, "
|
||
|
|
f"path={avg_path_length:.0f}"
|
||
|
|
)
|
||
|
|
|
||
|
|
self.save_to_csv(results)
|
||
|
|
|
||
|
|
# =====================================================
|
||
|
|
# Save CSV
|
||
|
|
# =====================================================
|
||
|
|
|
||
|
|
@staticmethod
|
||
|
|
def save_to_csv(results):
|
||
|
|
|
||
|
|
base_dir = os.path.dirname(__file__)
|
||
|
|
|
||
|
|
csv_path = os.path.join(
|
||
|
|
base_dir,
|
||
|
|
"benchmark_results.csv"
|
||
|
|
)
|
||
|
|
|
||
|
|
with open(
|
||
|
|
csv_path,
|
||
|
|
"w",
|
||
|
|
newline="",
|
||
|
|
encoding="utf-8"
|
||
|
|
) as file:
|
||
|
|
|
||
|
|
writer = csv.DictWriter(
|
||
|
|
file,
|
||
|
|
fieldnames=[
|
||
|
|
"maze",
|
||
|
|
"strategy",
|
||
|
|
"time_ms",
|
||
|
|
"visited_cells",
|
||
|
|
"path_length"
|
||
|
|
]
|
||
|
|
)
|
||
|
|
|
||
|
|
writer.writeheader()
|
||
|
|
|
||
|
|
for row in results:
|
||
|
|
|
||
|
|
writer.writerow(row)
|
||
|
|
|
||
|
|
print()
|
||
|
|
print(
|
||
|
|
f"Results saved to: {csv_path}"
|
||
|
|
)
|