import matplotlib.pyplot as plt import csv import numpy as np import os plt.rcParams['font.size'] = 10 plt.rcParams['font.family'] = 'sans-serif' def plot_results(csv_file="docs/data/results.csv"): if not os.path.exists(csv_file): print(f"Файл {csv_file} не найден. Сначала запустите benchmark.py") return data = {} with open(csv_file, 'r', encoding='utf-8') as f: reader = csv.reader(f) next(reader) for row in reader: if len(row) < 5: continue struct, mode, op, _, time_val = row try: time_val = float(time_val) except: continue if struct not in data: data[struct] = {} if mode not in data[struct]: data[struct][mode] = {} if op not in data[struct][mode]: data[struct][mode][op] = [] data[struct][mode][op].append(time_val) operations = ['вставка', 'поиск', 'удаление'] op_names = ['Вставка', 'Поиск', 'Удаление'] structures = ['LinkedList', 'HashTable', 'BST'] modes = ['случайный', 'отсортированный'] colors = {'LinkedList': '#3498db', 'HashTable': '#2ecc71', 'BST': '#e74c3c'} fig, axes = plt.subplots(1, 3, figsize=(14, 5)) fig.suptitle('Сравнение производительности структур данных\n(500 записей, 3 повторения)', fontsize=14, fontweight='bold') for idx, (op, op_name) in enumerate(zip(operations, op_names)): ax = axes[idx] x_positions = [] labels = [] values = [] errors = [] colors_list = [] position = 0 for struct in structures: for mode in modes: if struct in data and mode in data[struct] and op in data[struct][mode]: times = data[struct][mode][op] if times: avg_time = np.mean(times) std_time = np.std(times) if len(times) > 1 else 0 x_positions.append(position) labels.append(f'{struct}\n({mode[:4]})') values.append(avg_time) errors.append(std_time) colors_list.append(colors[struct]) position += 1 bars = ax.bar(x_positions, values, yerr=errors, capsize=5, color=colors_list, alpha=0.8, edgecolor='black', linewidth=0.5) ax.set_xticks(x_positions) ax.set_xticklabels(labels, fontsize=8, rotation=45, ha='right') ax.set_ylabel('Время (секунды)', fontsize=10) ax.set_title(f'{op_name}', fontsize=12, fontweight='bold') ax.grid(True, alpha=0.3, axis='y') for bar, val in zip(bars, values): if val > 0: height = bar.get_height() ax.text(bar.get_x() + bar.get_width()/2., height + max(values)*0.02, f'{val:.4f}', ha='center', va='bottom', fontsize=7, rotation=0) plt.tight_layout() plt.savefig('docs/data/performance_graphs.png', dpi=300, bbox_inches='tight') plt.show() fig2, ax2 = plt.subplots(figsize=(10, 6)) fig2.suptitle('Влияние порядка данных на производительность BST', fontsize=14, fontweight='bold') if 'BST' in data: bst_data = data['BST'] x_pos = [] labels = [] random_vals = [] sorted_vals = [] for idx, op in enumerate(operations): random_time = 0 sorted_time = 0 if 'случайный' in bst_data and op in bst_data['случайный']: random_time = np.mean(bst_data['случайный'][op]) if 'отсортированный' in bst_data and op in bst_data['отсортированный']: sorted_time = np.mean(bst_data['отсортированный'][op]) x_pos.append(idx) x_pos.append(idx + 0.35) labels.append(op) random_vals.append(random_time) sorted_vals.append(sorted_time) width = 0.35 bars1 = ax2.bar([i - width/2 for i in range(len(operations))], random_vals, width, label='Случайный порядок', color='#2ecc71', alpha=0.8, edgecolor='black') bars2 = ax2.bar([i + width/2 for i in range(len(operations))], sorted_vals, width, label='Отсортированный порядок', color='#e74c3c', alpha=0.8, edgecolor='black') ax2.set_xticks(range(len(operations))) ax2.set_xticklabels(['Вставка', 'Поиск', 'Удаление'], fontsize=10) ax2.set_ylabel('Время (секунды)', fontsize=10) ax2.set_xlabel('Операция', fontsize=10) ax2.legend(fontsize=10) ax2.grid(True, alpha=0.3, axis='y') for bar, val in zip(bars1, random_vals): if val > 0: ax2.text(bar.get_x() + bar.get_width()/2., bar.get_height() + max(random_vals + sorted_vals)*0.02, f'{val:.4f}', ha='center', va='bottom', fontsize=8) for bar, val in zip(bars2, sorted_vals): if val > 0: ax2.text(bar.get_x() + bar.get_width()/2., bar.get_height() + max(random_vals + sorted_vals)*0.02, f'{val:.4f}', ha='center', va='bottom', fontsize=8) plt.tight_layout() plt.savefig('docs/data/bst_comparison.png', dpi=300, bbox_inches='tight') plt.show() print("\n" + "="*60) print("ИТОГОВАЯ ТАБЛИЦА РЕЗУЛЬТАТОВ") print("="*60) print(f"{'Структура':<15} {'Режим':<12} {'Вставка':<12} {'Поиск':<12} {'Удаление':<12}") print("-"*60) for struct in structures: for mode in modes: if struct in data and mode in data[struct]: insert_times = data[struct][mode].get('вставка', [0]) find_times = data[struct][mode].get('поиск', [0]) delete_times = data[struct][mode].get('удаление', [0]) insert_avg = np.mean(insert_times) if insert_times else 0 find_avg = np.mean(find_times) if find_times else 0 delete_avg = np.mean(delete_times) if delete_times else 0 print(f"{struct:<15} {mode:<12} {insert_avg:<12.6f} {find_avg:<12.6f} {delete_avg:<12.6f}") print("="*60) if __name__ == "__main__": plot_results()