[5] finally
363
agafonovdm/docs/data/2zad/RESULT22.py
Normal file
|
|
@ -0,0 +1,363 @@
|
|||
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()
|
||||
BIN
agafonovdm/docs/data/2zad/efficiency_ratio.png
Normal file
|
After Width: | Height: | Size: 71 KiB |
BIN
agafonovdm/docs/data/2zad/path_length.png
Normal file
|
After Width: | Height: | Size: 61 KiB |
BIN
agafonovdm/docs/data/2zad/path_vs_visited.png
Normal file
|
After Width: | Height: | Size: 58 KiB |
BIN
agafonovdm/docs/data/2zad/time_Empty_30x30.png
Normal file
|
After Width: | Height: | Size: 47 KiB |
BIN
agafonovdm/docs/data/2zad/time_Large_100x100.png
Normal file
|
After Width: | Height: | Size: 47 KiB |
BIN
agafonovdm/docs/data/2zad/time_Medium_50x50.png
Normal file
|
After Width: | Height: | Size: 46 KiB |
BIN
agafonovdm/docs/data/2zad/time_No_Exit_20x20.png
Normal file
|
After Width: | Height: | Size: 46 KiB |
BIN
agafonovdm/docs/data/2zad/time_Small_10x10.png
Normal file
|
After Width: | Height: | Size: 49 KiB |
BIN
agafonovdm/docs/data/2zad/time_comparison.png
Normal file
|
After Width: | Height: | Size: 93 KiB |
BIN
agafonovdm/docs/data/2zad/visited_Empty_30x30.png
Normal file
|
After Width: | Height: | Size: 44 KiB |
BIN
agafonovdm/docs/data/2zad/visited_Large_100x100.png
Normal file
|
After Width: | Height: | Size: 50 KiB |
BIN
agafonovdm/docs/data/2zad/visited_Medium_50x50.png
Normal file
|
After Width: | Height: | Size: 48 KiB |
BIN
agafonovdm/docs/data/2zad/visited_No_Exit_20x20.png
Normal file
|
After Width: | Height: | Size: 47 KiB |
BIN
agafonovdm/docs/data/2zad/visited_Small_10x10.png
Normal file
|
After Width: | Height: | Size: 44 KiB |
BIN
agafonovdm/docs/data/2zad/visited_cells.png
Normal file
|
After Width: | Height: | Size: 82 KiB |