2026-rff_mp/MarkinAM/2/experiment.py
2026-05-25 09:57:30 +03:00

138 lines
5.4 KiB
Python
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.

import csv
import os
import statistics
import matplotlib.pyplot as plt
from maze_builder import TextFileMazeBuilder
from solver import MazeSolver
from strategies import BFSStrategy, DFSStrategy, AStarStrategy
# --- НАСТРОЙКИ ---
MAZES_DIR = "mazes"
OUTPUT_CSV = "results.csv"
RUNS = 10 # Количество запусков для усреднения
PLOTS_DIR = "plots" # Новая папка для графиков
STRATEGIES = {
"BFS": BFSStrategy,
"DFS": DFSStrategy,
"A*": AStarStrategy,
}
# Словарь для хранения всех данных для графиков
all_data = {}
# Создаем папку для графиков, если её нет
os.makedirs(PLOTS_DIR, exist_ok=True)
builder = TextFileMazeBuilder()
maze_files = sorted(f for f in os.listdir(MAZES_DIR) if f.endswith(".txt"))
rows = []
print("=== СТАРТ ЭКСПЕРИМЕНТА ===\n")
# --- ОСНОВНОЙ ЦИКЛ ЭКСПЕРИМЕНТА ---
for maze_file in maze_files:
maze_name = maze_file.replace(".txt", "")
filepath = os.path.join(MAZES_DIR, maze_file)
try:
maze = builder.build_from_file(filepath)
except ValueError as e:
print(f" [!] Пропуск {maze_file}: {e}")
continue # Переходим к следующему файлу, если этот не загрузился
# Эта строка теперь выполняется для каждого успешного лабиринта
print(f"\n{'='*50}")
print(f"Лабиринт: {maze_name} ({maze.width}×{maze.height})")
all_data[maze_name] = {}
for strat_name, StratClass in STRATEGIES.items():
times, visited_counts, path_lengths = [], [], []
run_stats = []
for run_num in range(1, RUNS + 1):
solver = MazeSolver(maze, StratClass())
stats = solver.solve()
times.append(stats.time_ms)
visited_counts.append(stats.visited_cells)
path_lengths.append(stats.path_length)
# Сохраняем данные каждой попытки
run_stats.append({
'попытка': run_num,
'время_мс': stats.time_ms,
'посещено_клеток': stats.visited_cells,
'длина_пути': stats.path_length
})
print(f" {strat_name} | Попытка {run_num}/{RUNS} | Время: {stats.time_ms:.2f} мс")
# Вычисляем средние значения
avg_time = statistics.mean(times)
avg_visited = statistics.mean(visited_counts)
valid_path_lengths = [p for p in path_lengths if p is not None]
avg_path = statistics.mean(valid_path_lengths) if valid_path_lengths else None
print(f" {strat_name:10s} | СРЕДНЕЕ: время {avg_time:.2f} мс | "
f"посещено {avg_visited:.1f} | путь {avg_path if avg_path is not None else ''}")
rows.append({
"лабиринт": maze_name,
"стратегия": strat_name,
"время_мс": round(avg_time, 6),
"посещено_клеток": round(avg_visited, 1),
"длина_пути": round(avg_path, 1) if avg_path is not None else None,
})
all_data[maze_name][strat_name] = run_stats
# --- СОХРАНЕНИЕ CSV ---
with open(OUTPUT_CSV, "w", newline="", encoding="utf-8") as csvfile:
fieldnames = ["лабиринт", "стратегия", "время_мс", "посещено_клеток", "длина_пути"]
writer = csv.DictWriter(csvfile, fieldnames=fieldnames)
writer.writeheader()
writer.writerows(rows)
print(f"\n✓ Результаты сохранены в {OUTPUT_CSV}")
# --- ПОСТРОЕНИЕ ГРАФИКОВ ---
print("\n=== ПОСТРОЕНИЕ ГРАФИКОВ ===")
for maze_name, strategies_data in all_data.items():
print(f"\nСтроим графики для лабиринта: {maze_name}")
# Создаем ОДИН график для времени выполнения
fig, ax = plt.subplots(figsize=(10, 6))
fig.suptitle(f"Сравнение времени выполнения алгоритмов\nЛабиринт '{maze_name}'", fontsize=14)
ax.set_title("Время выполнения (мс)")
ax.set_xlabel("Номер попытки")
ax.set_ylabel("Время (мс)")
for strat_name in STRATEGIES.keys():
# Извлекаем только данные о времени выполнения
data_points = [
run['время_мс'] for run in strategies_data.get(strat_name, [])
]
if data_points:
x_values = range(1, len(data_points) + 1)
ax.plot(x_values, data_points,
marker='o',
label=strat_name,
linewidth=2)
ax.legend(title="Алгоритм")
ax.grid(True, which='both', linestyle='--', linewidth=0.5)
plt.tight_layout(rect=[0, 0.03, 1, 0.95])
# Сохраняем график в папку 'plots'
plot_filename = os.path.join(PLOTS_DIR, f"plot_{maze_name}.png")
plt.savefig(plot_filename)
plt.close()
print(f"\n✓ Графики времени выполнения сохранены в папку '{PLOTS_DIR}'")
print("=== ЭКСПЕРИМЕНТ ЗАВЕРШЕН ===")