272 lines
10 KiB
Python
272 lines
10 KiB
Python
import pandas as pd
|
||
import matplotlib.pyplot as plt
|
||
import numpy as np
|
||
|
||
# Настройка русских шрифтов
|
||
plt.rcParams['font.family'] = 'DejaVu Sans'
|
||
plt.rcParams['axes.unicode_minus'] = False
|
||
|
||
def load_and_prepare_data(filename='experiment_results.csv'):
|
||
"""Загрузка данных из CSV и подготовка."""
|
||
df = pd.read_csv(filename, delimiter=';')
|
||
|
||
# Преобразование типов (если нужно)
|
||
numeric_cols = ['avg_time_ms', 'std_time_ms', 'avg_visited', 'avg_path_len']
|
||
for col in numeric_cols:
|
||
df[col] = pd.to_numeric(df[col], errors='coerce')
|
||
|
||
return df
|
||
|
||
def plot_time_comparison(df):
|
||
"""График 1: Сравнение времени выполнения по лабиринтам."""
|
||
fig, ax = plt.subplots(figsize=(12, 6))
|
||
|
||
maze_types = df['maze_type'].unique()
|
||
strategies = df['strategy'].unique()
|
||
|
||
x = np.arange(len(maze_types))
|
||
width = 0.2
|
||
|
||
colors = ['#1f77b4', '#ff7f0e', '#2ca02c', '#d62728']
|
||
|
||
for i, strategy in enumerate(strategies):
|
||
strategy_data = df[df['strategy'] == strategy]
|
||
times = []
|
||
errors = []
|
||
for maze in maze_types:
|
||
row = strategy_data[strategy_data['maze_type'] == maze]
|
||
if not row.empty:
|
||
times.append(row['avg_time_ms'].values[0])
|
||
errors.append(row['std_time_ms'].values[0])
|
||
else:
|
||
times.append(0)
|
||
errors.append(0)
|
||
|
||
bars = ax.bar(x + i*width, times, width, label=strategy,
|
||
color=colors[i], yerr=errors, capsize=3)
|
||
|
||
ax.set_xlabel('Тип лабиринта', fontsize=12)
|
||
ax.set_ylabel('Время выполнения (мс)', fontsize=12)
|
||
ax.set_title('Сравнение времени выполнения алгоритмов поиска пути', fontsize=14)
|
||
ax.set_xticks(x + width * 1.5)
|
||
ax.set_xticklabels(maze_types, rotation=45, ha='right')
|
||
ax.legend()
|
||
ax.grid(True, alpha=0.3, axis='y')
|
||
|
||
plt.tight_layout()
|
||
plt.savefig('time_comparison.png', dpi=150)
|
||
plt.show()
|
||
|
||
def plot_visited_cells(df):
|
||
"""График 2: Количество посещённых клеток."""
|
||
fig, ax = plt.subplots(figsize=(12, 6))
|
||
|
||
maze_types = df['maze_type'].unique()
|
||
strategies = df['strategy'].unique()
|
||
|
||
x = np.arange(len(maze_types))
|
||
width = 0.2
|
||
|
||
for i, strategy in enumerate(strategies):
|
||
strategy_data = df[df['strategy'] == strategy]
|
||
visited = []
|
||
for maze in maze_types:
|
||
row = strategy_data[strategy_data['maze_type'] == maze]
|
||
if not row.empty:
|
||
visited.append(row['avg_visited'].values[0])
|
||
else:
|
||
visited.append(0)
|
||
|
||
ax.bar(x + i*width, visited, width, label=strategy)
|
||
|
||
ax.set_xlabel('Тип лабиринта', fontsize=12)
|
||
ax.set_ylabel('Количество посещённых клеток', fontsize=12)
|
||
ax.set_title('Сравнение количества посещённых клеток', fontsize=14)
|
||
ax.set_xticks(x + width * 1.5)
|
||
ax.set_xticklabels(maze_types, rotation=45, ha='right')
|
||
ax.legend()
|
||
ax.grid(True, alpha=0.3, axis='y')
|
||
|
||
plt.tight_layout()
|
||
plt.savefig('visited_cells.png', dpi=150)
|
||
plt.show()
|
||
|
||
def plot_path_length(df):
|
||
"""График 3: Длина найденного пути."""
|
||
fig, ax = plt.subplots(figsize=(12, 6))
|
||
|
||
# Исключаем лабиринты без выхода (где путь = 0)
|
||
df_filtered = df[df['avg_path_len'] > 0]
|
||
|
||
maze_types = df_filtered['maze_type'].unique()
|
||
strategies = df_filtered['strategy'].unique()
|
||
|
||
x = np.arange(len(maze_types))
|
||
width = 0.2
|
||
|
||
for i, strategy in enumerate(strategies):
|
||
strategy_data = df_filtered[df_filtered['strategy'] == strategy]
|
||
path_lengths = []
|
||
for maze in maze_types:
|
||
row = strategy_data[strategy_data['maze_type'] == maze]
|
||
if not row.empty:
|
||
path_lengths.append(row['avg_path_len'].values[0])
|
||
else:
|
||
path_lengths.append(0)
|
||
|
||
ax.bar(x + i*width, path_lengths, width, label=strategy)
|
||
|
||
ax.set_xlabel('Тип лабиринта', fontsize=12)
|
||
ax.set_ylabel('Длина пути (количество клеток)', fontsize=12)
|
||
ax.set_title('Сравнение длины найденного пути', fontsize=14)
|
||
ax.set_xticks(x + width * 1.5)
|
||
ax.set_xticklabels(maze_types, rotation=45, ha='right')
|
||
ax.legend()
|
||
ax.grid(True, alpha=0.3, axis='y')
|
||
|
||
plt.tight_layout()
|
||
plt.savefig('path_length.png', dpi=150)
|
||
plt.show()
|
||
|
||
def plot_time_per_maze(df):
|
||
"""График 4: Для каждого лабиринта - сравнение стратегий."""
|
||
maze_types = df['maze_type'].unique()
|
||
strategies = df['strategy'].unique()
|
||
|
||
for maze in maze_types:
|
||
fig, ax = plt.subplots(figsize=(10, 6))
|
||
|
||
maze_data = df[df['maze_type'] == maze]
|
||
|
||
times = maze_data['avg_time_ms'].values
|
||
errors = maze_data['std_time_ms'].values
|
||
strategy_names = maze_data['strategy'].values
|
||
|
||
bars = ax.bar(strategy_names, times, yerr=errors, capsize=5,
|
||
color=['#1f77b4', '#ff7f0e', '#2ca02c', '#d62728'])
|
||
|
||
ax.set_xlabel('Алгоритм', fontsize=12)
|
||
ax.set_ylabel('Время выполнения (мс)', fontsize=12)
|
||
ax.set_title(f'Сравнение алгоритмов на лабиринте: {maze}', fontsize=14)
|
||
ax.grid(True, alpha=0.3, axis='y')
|
||
|
||
# Добавление значений на столбцы
|
||
for bar, time_val in zip(bars, times):
|
||
height = bar.get_height()
|
||
ax.text(bar.get_x() + bar.get_width()/2., height + max(errors)/2,
|
||
f'{time_val:.1f}', ha='center', va='bottom', fontsize=10)
|
||
|
||
plt.tight_layout()
|
||
plt.savefig(f'time_{maze}.png', dpi=150)
|
||
plt.show()
|
||
|
||
def plot_visited_per_maze(df):
|
||
"""График 5: Для каждого лабиринта - посещённые клетки."""
|
||
maze_types = df['maze_type'].unique()
|
||
|
||
for maze in maze_types:
|
||
fig, ax = plt.subplots(figsize=(10, 6))
|
||
|
||
maze_data = df[df['maze_type'] == maze]
|
||
|
||
visited = maze_data['avg_visited'].values
|
||
strategy_names = maze_data['strategy'].values
|
||
|
||
bars = ax.bar(strategy_names, visited,
|
||
color=['#1f77b4', '#ff7f0e', '#2ca02c', '#d62728'])
|
||
|
||
ax.set_xlabel('Алгоритм', fontsize=12)
|
||
ax.set_ylabel('Количество посещённых клеток', fontsize=12)
|
||
ax.set_title(f'Посещённые клетки на лабиринте: {maze}', fontsize=14)
|
||
ax.grid(True, alpha=0.3, axis='y')
|
||
|
||
# Добавление значений на столбцы
|
||
for bar, val in zip(bars, visited):
|
||
height = bar.get_height()
|
||
ax.text(bar.get_x() + bar.get_width()/2., height,
|
||
f'{int(val)}', ha='center', va='bottom', fontsize=10)
|
||
|
||
plt.tight_layout()
|
||
plt.savefig(f'visited_{maze}.png', dpi=150)
|
||
plt.show()
|
||
|
||
def plot_efficiency_ratio(df):
|
||
"""График 6: Эффективность (время на клетку пути)."""
|
||
fig, ax = plt.subplots(figsize=(12, 6))
|
||
|
||
# Исключаем лабиринты без пути
|
||
df_filtered = df[(df['avg_path_len'] > 0) & (df['avg_time_ms'] > 0)].copy()
|
||
df_filtered['efficiency'] = df_filtered['avg_time_ms'] / df_filtered['avg_path_len']
|
||
|
||
maze_types = df_filtered['maze_type'].unique()
|
||
strategies = df_filtered['strategy'].unique()
|
||
|
||
x = np.arange(len(maze_types))
|
||
width = 0.2
|
||
|
||
for i, strategy in enumerate(strategies):
|
||
strategy_data = df_filtered[df_filtered['strategy'] == strategy]
|
||
efficiency = []
|
||
for maze in maze_types:
|
||
row = strategy_data[strategy_data['maze_type'] == maze]
|
||
if not row.empty:
|
||
efficiency.append(row['efficiency'].values[0])
|
||
else:
|
||
efficiency.append(0)
|
||
|
||
ax.bar(x + i*width, efficiency, width, label=strategy)
|
||
|
||
ax.set_xlabel('Тип лабиринта', fontsize=12)
|
||
ax.set_ylabel('Время на клетку пути (мс/клетку)', fontsize=12)
|
||
ax.set_title('Эффективность алгоритмов (время на единицу длины пути)', fontsize=14)
|
||
ax.set_xticks(x + width * 1.5)
|
||
ax.set_xticklabels(maze_types, rotation=45, ha='right')
|
||
ax.legend()
|
||
ax.grid(True, alpha=0.3, axis='y')
|
||
|
||
plt.tight_layout()
|
||
plt.savefig('efficiency_ratio.png', dpi=150)
|
||
plt.show()
|
||
|
||
def main():
|
||
"""Основная функция: загрузка данных и построение всех графиков."""
|
||
try:
|
||
df = load_and_prepare_data('experiment_results.csv')
|
||
print("Данные успешно загружены")
|
||
print(f"Найдено {len(df)} записей")
|
||
print("\nСтруктура данных:")
|
||
print(df.head())
|
||
|
||
print("\nПостроение графиков...")
|
||
|
||
# Базовые графики
|
||
plot_time_comparison(df)
|
||
plot_visited_cells(df)
|
||
plot_path_length(df)
|
||
|
||
# Детальные графики по каждому лабиринту
|
||
plot_time_per_maze(df)
|
||
plot_visited_per_maze(df)
|
||
|
||
# Аналитические графики
|
||
plot_efficiency_ratio(df)
|
||
|
||
print("\nВсе графики сохранены в текущей директории:")
|
||
print(" - time_comparison.png")
|
||
print(" - visited_cells.png")
|
||
print(" - path_length.png")
|
||
print(" - time_{maze}.png (для каждого лабиринта)")
|
||
print(" - visited_{maze}.png (для каждого лабиринта)")
|
||
print(" - efficiency_ratio.png")
|
||
print(" - summary_heatmap.png")
|
||
|
||
except FileNotFoundError:
|
||
print("Ошибка: файл experiment_results.csv не найден")
|
||
print("Сначала запустите основной скрипт для генерации результатов")
|
||
except Exception as e:
|
||
print(f"Ошибка: {e}")
|
||
import traceback
|
||
traceback.print_exc()
|
||
|
||
if __name__ == "__main__":
|
||
main() |