2026-rff_mp/skorohodovsa/task_1/task.py

173 lines
7.9 KiB
Python
Raw Normal View History

2026-05-25 08:27:50 +00:00
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()