2026-rff_mp/agafonovdm/docs/data/2zad/RESULT22.py
2026-05-25 15:39:57 +03:00

363 lines
15 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 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=',') # Используем запятую как разделитель
# Переименовываем столбцы для удобства
df.columns = ['maze_type', 'algorithm', 'avg_time_ms', 'avg_visited_cells', 'avg_path_length']
# Преобразование типов
numeric_cols = ['avg_time_ms', 'avg_visited_cells', 'avg_path_length']
for col in numeric_cols:
df[col] = pd.to_numeric(df[col], errors='coerce')
# Добавляем столбец с размером лабиринта для анализа
def extract_maze_size(maze_name):
if 'Small' in maze_name:
return 'Small (10x10)'
elif 'Medium' in maze_name:
return 'Medium (50x50)'
elif 'Large' in maze_name:
return 'Large (100x100)'
elif 'Empty' in maze_name:
return 'Empty (30x30)'
elif 'No Exit' in maze_name:
return 'No Exit (20x20)'
return maze_name
df['maze_category'] = df['maze_type'].apply(extract_maze_size)
return df
def plot_time_comparison(df):
"""График 1: Сравнение времени выполнения по лабиринтам."""
fig, ax = plt.subplots(figsize=(12, 6))
maze_types = df['maze_category'].unique()
algorithms = df['algorithm'].unique()
x = np.arange(len(maze_types))
width = 0.2
colors = ['#1f77b4', '#ff7f0e', '#2ca02c', '#d62728']
for i, algorithm in enumerate(algorithms):
algo_data = df[df['algorithm'] == algorithm]
times = []
for maze in maze_types:
row = algo_data[algo_data['maze_category'] == maze]
if not row.empty:
times.append(row['avg_time_ms'].values[0])
else:
times.append(0)
bars = ax.bar(x + i*width, times, width, label=algorithm,
color=colors[i])
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')
# Добавление значений на столбцы
for i, algorithm in enumerate(algorithms):
algo_data = df[df['algorithm'] == algorithm]
for j, maze in enumerate(maze_types):
row = algo_data[algo_data['maze_category'] == maze]
if not row.empty and row['avg_time_ms'].values[0] > 0:
time_val = row['avg_time_ms'].values[0]
ax.text(x[j] + i*width, time_val + 0.02,
f'{time_val:.3f}', ha='center', va='bottom', fontsize=8)
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_category'].unique()
algorithms = df['algorithm'].unique()
x = np.arange(len(maze_types))
width = 0.2
colors = ['#1f77b4', '#ff7f0e', '#2ca02c', '#d62728']
for i, algorithm in enumerate(algorithms):
algo_data = df[df['algorithm'] == algorithm]
visited = []
for maze in maze_types:
row = algo_data[algo_data['maze_category'] == maze]
if not row.empty:
visited.append(row['avg_visited_cells'].values[0])
else:
visited.append(0)
ax.bar(x + i*width, visited, width, label=algorithm, color=colors[i])
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_length'] > 0]
maze_types = df_filtered['maze_category'].unique()
algorithms = df_filtered['algorithm'].unique()
x = np.arange(len(maze_types))
width = 0.2
colors = ['#1f77b4', '#ff7f0e', '#2ca02c', '#d62728']
for i, algorithm in enumerate(algorithms):
algo_data = df_filtered[df_filtered['algorithm'] == algorithm]
path_lengths = []
for maze in maze_types:
row = algo_data[algo_data['maze_category'] == maze]
if not row.empty:
path_lengths.append(row['avg_path_length'].values[0])
else:
path_lengths.append(0)
ax.bar(x + i*width, path_lengths, width, label=algorithm, color=colors[i])
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_category'].unique()
algorithms = df['algorithm'].unique()
for maze in maze_types:
fig, ax = plt.subplots(figsize=(10, 6))
maze_data = df[df['maze_category'] == maze]
times = []
algo_names = []
for algo in algorithms:
row = maze_data[maze_data['algorithm'] == algo]
if not row.empty:
times.append(row['avg_time_ms'].values[0])
algo_names.append(algo)
bars = ax.bar(algo_names, times,
color=['#1f77b4', '#ff7f0e', '#2ca02c', '#d62728'][:len(algo_names)])
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 + 0.02,
f'{time_val:.3f}', ha='center', va='bottom', fontsize=10)
plt.tight_layout()
# Очищаем имя файла от скобок
safe_maze_name = maze.replace('(', '').replace(')', '').replace(' ', '_')
plt.savefig(f'time_{safe_maze_name}.png', dpi=150)
plt.show()
def plot_visited_per_maze(df):
"""График 5: Для каждого лабиринта - посещённые клетки."""
maze_types = df['maze_category'].unique()
for maze in maze_types:
fig, ax = plt.subplots(figsize=(10, 6))
maze_data = df[df['maze_category'] == maze]
visited = maze_data['avg_visited_cells'].values
algo_names = maze_data['algorithm'].values
bars = ax.bar(algo_names, visited,
color=['#1f77b4', '#ff7f0e', '#2ca02c', '#d62728'][:len(algo_names)])
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 + 10,
f'{int(val)}', ha='center', va='bottom', fontsize=10)
plt.tight_layout()
safe_maze_name = maze.replace('(', '').replace(')', '').replace(' ', '_')
plt.savefig(f'visited_{safe_maze_name}.png', dpi=150)
plt.show()
def plot_efficiency_ratio(df):
"""График 6: Эффективность (время на клетку пути)."""
fig, ax = plt.subplots(figsize=(12, 6))
# Исключаем лабиринты без пути
df_filtered = df[(df['avg_path_length'] > 0) & (df['avg_time_ms'] > 0)].copy()
df_filtered['efficiency'] = df_filtered['avg_time_ms'] / df_filtered['avg_path_length']
maze_types = df_filtered['maze_category'].unique()
algorithms = df_filtered['algorithm'].unique()
x = np.arange(len(maze_types))
width = 0.2
colors = ['#1f77b4', '#ff7f0e', '#2ca02c', '#d62728']
for i, algorithm in enumerate(algorithms):
algo_data = df_filtered[df_filtered['algorithm'] == algorithm]
efficiency = []
for maze in maze_types:
row = algo_data[algo_data['maze_category'] == maze]
if not row.empty:
efficiency.append(row['efficiency'].values[0])
else:
efficiency.append(0)
ax.bar(x + i*width, efficiency, width, label=algorithm, color=colors[i])
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 plot_path_vs_visited(df):
"""График 7: Соотношение длины пути и посещённых клеток."""
fig, ax = plt.subplots(figsize=(10, 6))
algorithms = df['algorithm'].unique()
markers = ['o', 's', '^', 'D']
colors = ['#1f77b4', '#ff7f0e', '#2ca02c', '#d62728']
for algo, marker, color in zip(algorithms, markers, colors):
algo_data = df[df['algorithm'] == algo]
# Только лабиринты с путём
algo_data = algo_data[algo_data['avg_path_length'] > 0]
if not algo_data.empty:
plt.scatter(algo_data['avg_visited_cells'],
algo_data['avg_path_length'],
marker=marker, s=100, label=algo, color=color, alpha=0.7)
# Добавляем подписи для каждой точки
for _, row in algo_data.iterrows():
plt.annotate(row['maze_category'].split()[0],
(row['avg_visited_cells'], row['avg_path_length']),
xytext=(5, 5), textcoords='offset points', fontsize=8)
plt.xlabel('Количество посещённых клеток', fontsize=12)
plt.ylabel('Длина пути (клеток)', fontsize=12)
plt.title('Соотношение: посещённые клетки vs длина пути', fontsize=14)
plt.legend()
plt.grid(True, alpha=0.3)
plt.tight_layout()
plt.savefig('path_vs_visited.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Уникальные типы лабиринтов:")
print(df['maze_category'].unique())
print("\nУникальные алгоритмы:")
print(df['algorithm'].unique())
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)
plot_path_vs_visited(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(" - path_vs_visited.png")
# Вывод статистики
print("\n=== Краткая статистика ===")
for maze in df['maze_category'].unique():
print(f"\n{maze}:")
maze_data = df[df['maze_category'] == maze]
for algo in df['algorithm'].unique():
algo_data = maze_data[maze_data['algorithm'] == algo]
if not algo_data.empty:
time_val = algo_data['avg_time_ms'].values[0]
visited_val = int(algo_data['avg_visited_cells'].values[0])
path_val = int(algo_data['avg_path_length'].values[0])
print(f" {algo}: время={time_val:.6f}мс, посещено={visited_val}, путь={path_val}")
except FileNotFoundError:
print("Ошибка: файл experiment_results.csv не найден")
print("Убедитесь, что файл находится в текущей директории")
except Exception as e:
print(f"Ошибка: {e}")
import traceback
traceback.print_exc()
if __name__ == "__main__":
main()