forked from UNN/2026-rff_mp
173 lines
7.9 KiB
Python
173 lines
7.9 KiB
Python
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() |