forked from UNN/2026-rff_mp
100 lines
3.8 KiB
Python
100 lines
3.8 KiB
Python
|
|
"""plot_results.py - графики для эксперимента с лабиринтами."""
|
|||
|
|
import csv
|
|||
|
|
import os
|
|||
|
|
import matplotlib.pyplot as plt
|
|||
|
|
import numpy as np
|
|||
|
|
|
|||
|
|
CSV = "docs/data/results.csv"
|
|||
|
|
PLOTS = "docs/data/plots"
|
|||
|
|
os.makedirs(PLOTS, exist_ok=True)
|
|||
|
|
|
|||
|
|
|
|||
|
|
def load_means():
|
|||
|
|
"""Возвращает dict[(maze, strategy)] = (time_ms, visited, path_len, cost)."""
|
|||
|
|
out = {}
|
|||
|
|
with open(CSV, encoding="utf-8") as f:
|
|||
|
|
rows = list(csv.reader(f))
|
|||
|
|
start = next(i for i, r in enumerate(rows) if r and r[0] == "--- СРЕДНИЕ ---") + 2
|
|||
|
|
for r in rows[start:]:
|
|||
|
|
if not r:
|
|||
|
|
continue
|
|||
|
|
maze, strat, t, vis, plen, cost = r
|
|||
|
|
out[(maze, strat)] = (float(t), int(vis), int(plen), int(cost))
|
|||
|
|
return out
|
|||
|
|
|
|||
|
|
|
|||
|
|
MAZES = ["small_10x10", "medium_51x51", "large_101x101",
|
|||
|
|
"empty_30x30", "nopath_15x15",
|
|||
|
|
"weighted_31x31", "weighted_choice"]
|
|||
|
|
STRATEGIES = ["BFS", "DFS", "A*", "Dijkstra"]
|
|||
|
|
COLORS = {"BFS": "#3498db", "DFS": "#e67e22", "A*": "#2ecc71", "Dijkstra": "#9b59b6"}
|
|||
|
|
|
|||
|
|
|
|||
|
|
def grouped_bar(means, idx, ylabel, title, fname, log=True):
|
|||
|
|
x = np.arange(len(MAZES))
|
|||
|
|
w = 0.2
|
|||
|
|
fig, ax = plt.subplots(figsize=(11, 5))
|
|||
|
|
for i, s in enumerate(STRATEGIES):
|
|||
|
|
vals = [means[(m, s)][idx] for m in MAZES]
|
|||
|
|
bars = ax.bar(x + (i - 1.5) * w, vals, w, label=s, color=COLORS[s], alpha=0.9)
|
|||
|
|
for b, v in zip(bars, vals):
|
|||
|
|
ax.text(b.get_x() + b.get_width() / 2, b.get_height(),
|
|||
|
|
f"{v:g}", ha="center", va="bottom", fontsize=7, rotation=0)
|
|||
|
|
ax.set_xticks(x)
|
|||
|
|
ax.set_xticklabels(MAZES, rotation=20, ha="right")
|
|||
|
|
ax.set_ylabel(ylabel)
|
|||
|
|
ax.set_title(title)
|
|||
|
|
if log:
|
|||
|
|
ax.set_yscale("log")
|
|||
|
|
ax.legend()
|
|||
|
|
ax.grid(axis="y", linestyle="--", alpha=0.4)
|
|||
|
|
plt.tight_layout()
|
|||
|
|
p = os.path.join(PLOTS, fname)
|
|||
|
|
plt.savefig(p, dpi=130)
|
|||
|
|
plt.close()
|
|||
|
|
print("saved:", p)
|
|||
|
|
|
|||
|
|
|
|||
|
|
def weighted_choice_chart(means):
|
|||
|
|
"""Отдельный график для weighted_choice: путь vs стоимость."""
|
|||
|
|
strategies = STRATEGIES
|
|||
|
|
lengths = [means[("weighted_choice", s)][2] for s in strategies]
|
|||
|
|
costs = [means[("weighted_choice", s)][3] for s in strategies]
|
|||
|
|
x = np.arange(len(strategies))
|
|||
|
|
w = 0.35
|
|||
|
|
fig, ax = plt.subplots(figsize=(7.5, 4.5))
|
|||
|
|
b1 = ax.bar(x - w/2, lengths, w, label="длина пути (клеток)",
|
|||
|
|
color="#3498db", alpha=0.9)
|
|||
|
|
b2 = ax.bar(x + w/2, costs, w, label="стоимость пути (сумма весов)",
|
|||
|
|
color="#e74c3c", alpha=0.9)
|
|||
|
|
for bars in (b1, b2):
|
|||
|
|
for bar in bars:
|
|||
|
|
ax.text(bar.get_x() + bar.get_width() / 2, bar.get_height(),
|
|||
|
|
f"{bar.get_height():.0f}", ha="center", va="bottom", fontsize=9)
|
|||
|
|
ax.set_xticks(x); ax.set_xticklabels(strategies)
|
|||
|
|
ax.set_title("weighted_choice: BFS/DFS режут через болото,\n"
|
|||
|
|
"Dijkstra/A* находят более дешёвый обход")
|
|||
|
|
ax.set_ylabel("значение")
|
|||
|
|
ax.legend()
|
|||
|
|
ax.grid(axis="y", linestyle="--", alpha=0.4)
|
|||
|
|
plt.tight_layout()
|
|||
|
|
p = os.path.join(PLOTS, "weighted_choice_compare.png")
|
|||
|
|
plt.savefig(p, dpi=130)
|
|||
|
|
plt.close()
|
|||
|
|
print("saved:", p)
|
|||
|
|
|
|||
|
|
|
|||
|
|
def main():
|
|||
|
|
means = load_means()
|
|||
|
|
grouped_bar(means, 0, "Время, мс (среднее по 7 запускам, лог. шкала)",
|
|||
|
|
"Время поиска пути", "time_compare.png", log=True)
|
|||
|
|
grouped_bar(means, 1, "Число посещённых клеток (лог. шкала)",
|
|||
|
|
"Сколько клеток посетил алгоритм", "visited_compare.png", log=True)
|
|||
|
|
grouped_bar(means, 2, "Длина пути (клеток)",
|
|||
|
|
"Длина найденного пути", "path_compare.png", log=False)
|
|||
|
|
weighted_choice_chart(means)
|
|||
|
|
|
|||
|
|
|
|||
|
|
if __name__ == "__main__":
|
|||
|
|
main()
|