diff --git a/agafonovdm/docs/data/2zad/RESULT22.py b/agafonovdm/docs/data/2zad/RESULT22.py new file mode 100644 index 0000000..62cd70e --- /dev/null +++ b/agafonovdm/docs/data/2zad/RESULT22.py @@ -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() \ No newline at end of file diff --git a/agafonovdm/docs/data/2zad/efficiency_ratio.png b/agafonovdm/docs/data/2zad/efficiency_ratio.png new file mode 100644 index 0000000..2edc6d2 Binary files /dev/null and b/agafonovdm/docs/data/2zad/efficiency_ratio.png differ diff --git a/agafonovdm/docs/data/2zad/path_length.png b/agafonovdm/docs/data/2zad/path_length.png new file mode 100644 index 0000000..b8b08f7 Binary files /dev/null and b/agafonovdm/docs/data/2zad/path_length.png differ diff --git a/agafonovdm/docs/data/2zad/path_vs_visited.png b/agafonovdm/docs/data/2zad/path_vs_visited.png new file mode 100644 index 0000000..aa0c13d Binary files /dev/null and b/agafonovdm/docs/data/2zad/path_vs_visited.png differ diff --git a/agafonovdm/docs/data/2zad/time_Empty_30x30.png b/agafonovdm/docs/data/2zad/time_Empty_30x30.png new file mode 100644 index 0000000..ee520ab Binary files /dev/null and b/agafonovdm/docs/data/2zad/time_Empty_30x30.png differ diff --git a/agafonovdm/docs/data/2zad/time_Large_100x100.png b/agafonovdm/docs/data/2zad/time_Large_100x100.png new file mode 100644 index 0000000..430d9b3 Binary files /dev/null and b/agafonovdm/docs/data/2zad/time_Large_100x100.png differ diff --git a/agafonovdm/docs/data/2zad/time_Medium_50x50.png b/agafonovdm/docs/data/2zad/time_Medium_50x50.png new file mode 100644 index 0000000..0478456 Binary files /dev/null and b/agafonovdm/docs/data/2zad/time_Medium_50x50.png differ diff --git a/agafonovdm/docs/data/2zad/time_No_Exit_20x20.png b/agafonovdm/docs/data/2zad/time_No_Exit_20x20.png new file mode 100644 index 0000000..548ae32 Binary files /dev/null and b/agafonovdm/docs/data/2zad/time_No_Exit_20x20.png differ diff --git a/agafonovdm/docs/data/2zad/time_Small_10x10.png b/agafonovdm/docs/data/2zad/time_Small_10x10.png new file mode 100644 index 0000000..6e2f331 Binary files /dev/null and b/agafonovdm/docs/data/2zad/time_Small_10x10.png differ diff --git a/agafonovdm/docs/data/2zad/time_comparison.png b/agafonovdm/docs/data/2zad/time_comparison.png new file mode 100644 index 0000000..9e9b288 Binary files /dev/null and b/agafonovdm/docs/data/2zad/time_comparison.png differ diff --git a/agafonovdm/docs/data/2zad/visited_Empty_30x30.png b/agafonovdm/docs/data/2zad/visited_Empty_30x30.png new file mode 100644 index 0000000..a4e741c Binary files /dev/null and b/agafonovdm/docs/data/2zad/visited_Empty_30x30.png differ diff --git a/agafonovdm/docs/data/2zad/visited_Large_100x100.png b/agafonovdm/docs/data/2zad/visited_Large_100x100.png new file mode 100644 index 0000000..663ad83 Binary files /dev/null and b/agafonovdm/docs/data/2zad/visited_Large_100x100.png differ diff --git a/agafonovdm/docs/data/2zad/visited_Medium_50x50.png b/agafonovdm/docs/data/2zad/visited_Medium_50x50.png new file mode 100644 index 0000000..7c94c5e Binary files /dev/null and b/agafonovdm/docs/data/2zad/visited_Medium_50x50.png differ diff --git a/agafonovdm/docs/data/2zad/visited_No_Exit_20x20.png b/agafonovdm/docs/data/2zad/visited_No_Exit_20x20.png new file mode 100644 index 0000000..de8ecdd Binary files /dev/null and b/agafonovdm/docs/data/2zad/visited_No_Exit_20x20.png differ diff --git a/agafonovdm/docs/data/2zad/visited_Small_10x10.png b/agafonovdm/docs/data/2zad/visited_Small_10x10.png new file mode 100644 index 0000000..f0d7138 Binary files /dev/null and b/agafonovdm/docs/data/2zad/visited_Small_10x10.png differ diff --git a/agafonovdm/docs/data/2zad/visited_cells.png b/agafonovdm/docs/data/2zad/visited_cells.png new file mode 100644 index 0000000..f657cbd Binary files /dev/null and b/agafonovdm/docs/data/2zad/visited_cells.png differ diff --git a/agafonovdm/docs/otchet1.docx b/agafonovdm/docs/otchet1.docx new file mode 100644 index 0000000..44124b4 Binary files /dev/null and b/agafonovdm/docs/otchet1.docx differ diff --git a/agafonovdm/docs/otchet2.docx b/agafonovdm/docs/otchet2.docx new file mode 100644 index 0000000..37643b3 Binary files /dev/null and b/agafonovdm/docs/otchet2.docx differ