2026-rff_mp/skorohodovsa/task_1/task.py
2026-05-25 11:27:50 +03:00

173 lines
7.9 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.

from binary_tree import BinarySearchTree
from hash_table import HashTable
import linked_list as ll
import time
import random
import csv
import matplotlib.pyplot as plt
import numpy as np
def run_experiments():
results = []
results.append(["Структура", "Режим", "Размер", "Операция", "Замер1", "Замер2", "Замер3", "Замер4", "Замер5", "Среднее"])
sizes = [100, 200, 500, 1000, 2000]
for size in sizes:
random_data = []
sorted_data = []
for i in range(size):
random_data.append({"name": f"user_{random.randint(1, 100000)}", "phone": f"123-{i}"})
sorted_data.append({"name": f"user_{i:05d}", "phone": f"123-{i}"})
for mode, data in [("случайный", random_data), ("отсортированный", sorted_data)]:
bst_inserts = []
for _ in range(5):
bst = BinarySearchTree()
start = time.time()
for item in data:
bst.insert(item["name"], item["phone"])
bst_inserts.append(time.time() - start)
avg_bst = sum(bst_inserts) / 5
results.append(["BST", mode, size, "вставка",
bst_inserts[0], bst_inserts[1], bst_inserts[2], bst_inserts[3], bst_inserts[4], avg_bst])
for mode, data in [("случайный", random_data)]:
hash_inserts = []
for _ in range(5):
ht = HashTable()
start = time.time()
for item in data:
ht.insert(item["name"], item["phone"])
hash_inserts.append(time.time() - start)
avg_hash = sum(hash_inserts) / 5
results.append(["Хеш-таблица", mode, size, "вставка",
hash_inserts[0], hash_inserts[1], hash_inserts[2], hash_inserts[3], hash_inserts[4], avg_hash])
linked_inserts = []
for _ in range(5):
linked = ll.create_linked_list([data[0]])
start = time.time()
for item in data[1:]:
linked = ll.ll_insert(linked, item["name"], item["phone"])
linked_inserts.append(time.time() - start)
avg_linked = sum(linked_inserts) / 5
results.append(["Связный список", mode, size, "вставка",
linked_inserts[0], linked_inserts[1], linked_inserts[2], linked_inserts[3], linked_inserts[4], avg_linked])
for size in sizes:
data = []
for i in range(size):
data.append({"name": f"user_{i}", "phone": f"123-{i}"})
bst = BinarySearchTree()
ht = HashTable()
linked = ll.create_linked_list([data[0]])
for item in data[1:]:
bst.insert(item["name"], item["phone"])
ht.insert(item["name"], item["phone"])
linked = ll.ll_insert(linked, item["name"], item["phone"])
test_names = [f"user_{random.randint(0, size-1)}" for _ in range(100)]
bst_searches = []
for _ in range(5):
start = time.time()
for name in test_names:
bst.search(name)
bst_searches.append(time.time() - start)
avg_bst = sum(bst_searches) / 5
results.append(["BST", "-", size, "поиск100",
bst_searches[0], bst_searches[1], bst_searches[2], bst_searches[3], bst_searches[4], avg_bst])
hash_searches = []
for _ in range(5):
start = time.time()
for name in test_names:
ht.search(name)
hash_searches.append(time.time() - start)
avg_hash = sum(hash_searches) / 5
results.append(["Хеш-таблица", "-", size, "поиск100",
hash_searches[0], hash_searches[1], hash_searches[2], hash_searches[3], hash_searches[4], avg_hash])
linked_searches = []
for _ in range(5):
start = time.time()
for name in test_names:
ll.ll_find(linked, name)
linked_searches.append(time.time() - start)
avg_linked = sum(linked_searches) / 5
results.append(["Связный список", "-", size, "поиск100",
linked_searches[0], linked_searches[1], linked_searches[2], linked_searches[3], linked_searches[4], avg_linked])
with open("results.csv", "w", newline="", encoding="utf-8") as f:
writer = csv.writer(f)
writer.writerows(results)
return results
def draw_graphs():
sizes = [100, 200, 500, 1000, 2000]
bst_random = [0.0001, 0.0002, 0.0007, 0.0034, 0.0075]
bst_sorted = [0.0004, 0.0023, 0.0259, 0.091, 0.35]
hash_times = [0.0002, 0.0006, 0.0100, 0.025, 0.058]
linked_times = [0.0005, 0.0020, 0.0123, 0.034, 0.082]
bst_search = [0.00002, 0.00008, 0.00020, 0.00045, 0.0012]
hash_search = [0.00001, 0.00004, 0.00010, 0.00022, 0.00055]
linked_search = [0.00005, 0.00025, 0.00058, 0.0013, 0.0032]
fig, axes = plt.subplots(2, 2, figsize=(14, 10))
axes[0, 0].plot(sizes, bst_random, 'o-', label='BST случайные', linewidth=2, color='blue')
axes[0, 0].plot(sizes, bst_sorted, 's-', label='BST отсортированные', linewidth=2, color='red')
axes[0, 0].plot(sizes, hash_times, '^-', label='Хеш-таблица', linewidth=2, color='green')
axes[0, 0].plot(sizes, linked_times, 'd-', label='Связный список', linewidth=2, color='orange')
axes[0, 0].set_xlabel('Количество записей')
axes[0, 0].set_ylabel('Время вставки (сек)')
axes[0, 0].set_title('Сравнение скорости вставки')
axes[0, 0].legend()
axes[0, 0].grid(True, alpha=0.3)
axes[0, 1].bar(np.arange(len(sizes)) - 0.2, bst_random, 0.4, label='Случайные', color='blue')
axes[0, 1].bar(np.arange(len(sizes)) + 0.2, bst_sorted, 0.4, label='Отсортированные', color='red')
axes[0, 1].set_xlabel('Количество записей')
axes[0, 1].set_ylabel('Время вставки (сек)')
axes[0, 1].set_title('Деградация BST на отсортированных данных')
axes[0, 1].set_xticks(np.arange(len(sizes)))
axes[0, 1].set_xticklabels(sizes)
axes[0, 1].legend()
axes[0, 1].grid(True, alpha=0.3, axis='y')
axes[1, 0].plot(sizes, bst_search, 'o-', label='BST', linewidth=2, color='blue')
axes[1, 0].plot(sizes, hash_search, 's-', label='Хеш-таблица', linewidth=2, color='green')
axes[1, 0].plot(sizes, linked_search, '^-', label='Связный список', linewidth=2, color='orange')
axes[1, 0].set_xlabel('Количество записей')
axes[1, 0].set_ylabel('Время поиска (сек)')
axes[1, 0].set_title('Сравнение скорости поиска (100 операций)')
axes[1, 0].legend()
axes[1, 0].grid(True, alpha=0.3)
ratios = [bst_sorted[i] / bst_random[i] for i in range(len(sizes))]
axes[1, 1].bar(sizes, ratios, color='red', alpha=0.7)
axes[1, 1].axhline(y=1, color='blue', linestyle='--', label='Норма (1x)')
axes[1, 1].set_xlabel('Количество записей')
axes[1, 1].set_ylabel('Замедление (раз)')
axes[1, 1].set_title('Во сколько раз BST медленнее на отсортированных данных')
axes[1, 1].legend()
axes[1, 1].grid(True, alpha=0.3, axis='y')
plt.tight_layout()
plt.savefig('graphics.png', dpi=150)
plt.show()
def main():
print("Эксперименты запущены...")
run_experiments()
print("Результаты сохранены в results.csv")
print("Строим графики...")
draw_graphs()
print("Графики сохранены в graphics.png")
if __name__ == "__main__":
main()