2026-05-19 19:35:33 +00:00
|
|
|
|
import csv
|
|
|
|
|
|
import time
|
|
|
|
|
|
import os
|
|
|
|
|
|
import matplotlib.pyplot as plt
|
|
|
|
|
|
import numpy as np
|
|
|
|
|
|
|
|
|
|
|
|
from MazeBuilder import TextFileMazeBuilder
|
|
|
|
|
|
from MazeSolver import MazeSolver, SearchStats
|
|
|
|
|
|
from DepthFirstSearch import DFSStrategy
|
|
|
|
|
|
from BreadthFirstSearch import BFSStrategy
|
|
|
|
|
|
from Deikstra import DeikstraFind
|
|
|
|
|
|
from AStarStrategy import AStarStrategy
|
2026-05-20 19:52:01 +00:00
|
|
|
|
from ConsoleView import ConsoleView
|
2026-05-19 19:35:33 +00:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def run_benchmarks():
|
2026-05-20 19:52:01 +00:00
|
|
|
|
|
|
|
|
|
|
files = ["mazes/maze_small.txt", "mazes/maze_empty.txt",
|
|
|
|
|
|
"mazes/maze_no_exit.txt", "mazes/maze_medium.txt", "mazes/maze_large.txt"]
|
2026-05-19 19:35:33 +00:00
|
|
|
|
strategies = {
|
|
|
|
|
|
"BFS": BFSStrategy(),
|
|
|
|
|
|
"DFS": DFSStrategy(),
|
|
|
|
|
|
"A*": AStarStrategy(),
|
|
|
|
|
|
"Deikstra": DeikstraFind()
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2026-05-20 19:52:01 +00:00
|
|
|
|
view = ConsoleView()
|
|
|
|
|
|
|
2026-05-19 19:35:33 +00:00
|
|
|
|
NUM_RUNS = 5
|
|
|
|
|
|
results = []
|
|
|
|
|
|
|
|
|
|
|
|
print("Запуск экспериментов...")
|
|
|
|
|
|
|
|
|
|
|
|
for file in files:
|
|
|
|
|
|
if not os.path.exists(file):
|
|
|
|
|
|
print(f"Файл {file} не найден. Пропуск.")
|
|
|
|
|
|
continue
|
|
|
|
|
|
|
|
|
|
|
|
for name, strategy in strategies.items():
|
|
|
|
|
|
total_time = 0.0
|
|
|
|
|
|
visited_counts = []
|
|
|
|
|
|
path_lengths = []
|
|
|
|
|
|
|
2026-05-20 19:52:01 +00:00
|
|
|
|
print(f" работает {name}")
|
2026-05-19 19:35:33 +00:00
|
|
|
|
for _ in range(NUM_RUNS):
|
|
|
|
|
|
# Пересоздаем лабиринт
|
|
|
|
|
|
builder = TextFileMazeBuilder()
|
|
|
|
|
|
builder.buildFromFile(file)
|
|
|
|
|
|
maze = builder.maze
|
|
|
|
|
|
|
|
|
|
|
|
solver = MazeSolver(maze, strategy)
|
2026-05-20 19:52:01 +00:00
|
|
|
|
|
|
|
|
|
|
solver.addObserver(view)
|
|
|
|
|
|
|
2026-05-19 19:35:33 +00:00
|
|
|
|
stats = solver.solve()
|
|
|
|
|
|
|
|
|
|
|
|
total_time += stats.execution_time
|
|
|
|
|
|
visited_counts.append(stats.visited_count)
|
|
|
|
|
|
path_lengths.append(stats.path_length)
|
|
|
|
|
|
|
|
|
|
|
|
# средние значения
|
|
|
|
|
|
avg_time = total_time / NUM_RUNS
|
|
|
|
|
|
avg_visited = int(np.mean(visited_counts))
|
|
|
|
|
|
avg_path = int(np.mean(path_lengths))
|
|
|
|
|
|
|
|
|
|
|
|
results.append({
|
|
|
|
|
|
"лабиринт": file,
|
|
|
|
|
|
"стратегия": name,
|
|
|
|
|
|
"время_мс": round(avg_time, 4),
|
|
|
|
|
|
"посещено_клеток": avg_visited,
|
|
|
|
|
|
"длина_пути": avg_path
|
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
|
|
# Запись в CSV
|
2026-05-20 19:52:01 +00:00
|
|
|
|
csv_file = "results/maze_benchmark_results.csv"
|
2026-05-19 19:35:33 +00:00
|
|
|
|
with open(csv_file, mode="w", encoding="utf-8", newline="") as f:
|
|
|
|
|
|
writer = csv.DictWriter(f, fieldnames=[
|
|
|
|
|
|
"лабиринт", "стратегия", "время_мс", "посещено_клеток", "длина_пути"])
|
|
|
|
|
|
writer.writeheader()
|
|
|
|
|
|
writer.writerows(results)
|
|
|
|
|
|
|
|
|
|
|
|
print(f"Результаты успешно сохранены в {csv_file}")
|
|
|
|
|
|
return results
|
|
|
|
|
|
|
|
|
|
|
|
# Построение графиков
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def plot_results(results):
|
|
|
|
|
|
print("Генерация графиков...")
|
|
|
|
|
|
mazes = sorted(list(set(r["лабиринт"] for r in results)))
|
|
|
|
|
|
strategies = ["BFS", "DFS", "A*"]
|
|
|
|
|
|
|
|
|
|
|
|
# График Количество посещенных клеток
|
|
|
|
|
|
fig, ax = plt.subplots(figsize=(10, 6))
|
|
|
|
|
|
x = np.arange(len(mazes))
|
|
|
|
|
|
width = 0.25
|
|
|
|
|
|
|
|
|
|
|
|
for i, strat in enumerate(strategies):
|
|
|
|
|
|
visited = [next(r["посещено_клеток"] for r in results if r["лабиринт"]
|
|
|
|
|
|
== m and r["стратегия"] == strat) for m in mazes]
|
|
|
|
|
|
ax.bar(x + i*width, visited, width, label=strat)
|
|
|
|
|
|
|
|
|
|
|
|
ax.set_ylabel('Количество посещенных клеток')
|
|
|
|
|
|
ax.set_title('Сравнение эффективности обхода лабиринтов (меньше = лучше)')
|
|
|
|
|
|
ax.set_xticks(x + width)
|
|
|
|
|
|
ax.set_xticklabels(mazes, rotation=15)
|
|
|
|
|
|
ax.legend()
|
|
|
|
|
|
plt.tight_layout()
|
2026-05-20 19:52:01 +00:00
|
|
|
|
plt.savefig("results/benchmark_visited_cells.png", dpi=200)
|
|
|
|
|
|
plt.savefig("results/benchmark_visited_cells.eps", dpi=200)
|
2026-05-19 19:35:33 +00:00
|
|
|
|
plt.close()
|
|
|
|
|
|
|
|
|
|
|
|
# График Время выполнения
|
|
|
|
|
|
fig, ax = plt.subplots(figsize=(10, 6))
|
|
|
|
|
|
for i, strat in enumerate(strategies):
|
|
|
|
|
|
times = [next(r["время_мс"] for r in results if r["лабиринт"]
|
|
|
|
|
|
== m and r["стратегия"] == strat) for m in mazes]
|
|
|
|
|
|
ax.bar(x + i*width, times, width, label=strat)
|
|
|
|
|
|
|
|
|
|
|
|
ax.set_ylabel('Время выполнения (мс)')
|
|
|
|
|
|
ax.set_title('Сравнение времени работы алгоритмов')
|
|
|
|
|
|
ax.set_xticks(x + width)
|
|
|
|
|
|
ax.set_xticklabels(mazes, rotation=15)
|
|
|
|
|
|
ax.legend()
|
|
|
|
|
|
plt.tight_layout()
|
2026-05-20 19:52:01 +00:00
|
|
|
|
plt.savefig("results/benchmark_execution_time.png", dpi=200)
|
|
|
|
|
|
plt.savefig("results/benchmark_execution_time.eps", dpi=200)
|
2026-05-19 19:35:33 +00:00
|
|
|
|
plt.close()
|
|
|
|
|
|
print("Графики сохранены в текущую директорию.")
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if __name__ == "__main__":
|
|
|
|
|
|
data = run_benchmarks()
|
|
|
|
|
|
plot_results(data)
|