106 lines
5.1 KiB
Python
106 lines
5.1 KiB
Python
import time
|
||
import random
|
||
import csv
|
||
import structures as st # Предполагается, что у вас есть модуль с реализациями структур данных
|
||
|
||
N=10000
|
||
REPEATS=5
|
||
|
||
# Генерируем список записей из N элементов, каждая запись - имя и телефон
|
||
def generate_records(N):
|
||
records = [
|
||
(f"User_{i:05d}", f"+7{random.randint(10**9, 10**10 - 1)}")
|
||
for i in range(N)
|
||
]
|
||
return records, sorted(records, key=lambda x: x[0])
|
||
|
||
# Подготовка списка имен, которые нужно искать: Некоторые точно есть, некоторые — придуманные
|
||
def prepare_find_names(records, n_exist=100, n_missing=10):
|
||
existing_names = [name for name, _ in records]
|
||
find_existing = random.sample(existing_names, n_exist) # Имена, которые есть
|
||
find_missing = [f"None_{i}" for i in range(n_missing)] # Не существующие имена
|
||
return find_existing + find_missing
|
||
|
||
# Подготовка списка имен для удаления
|
||
def prepare_delete_names(records, n_delete=50):
|
||
existing_names = [name for name, _ in records]
|
||
return random.sample(existing_names, n_delete) # случайные имена для удаления
|
||
|
||
# Обертка для измерения времени выполнения функции
|
||
def measure_time(func, *args):
|
||
start = time.perf_counter() # Точное время начала
|
||
result = func(*args) # Вызов функции
|
||
return result, time.perf_counter() - start # Возвращаем результат и время выполнения
|
||
|
||
# Определение структур данных и соответствующих функций для операций
|
||
STRUCTURES = [
|
||
("LinkedList", st.ll_insert, st.ll_find, st.ll_delete),
|
||
("HashTable", st.ht_insert, st.ht_find, st.ht_delete),
|
||
("BST", st.bst_insert, st.bst_find, st.bst_delete),
|
||
]
|
||
|
||
# Функция для построения структуры данных из записей и измерения времени вставки
|
||
def build_and_measure(build_func, records, init_val):
|
||
head = init_val
|
||
for name, phone in records:
|
||
head = build_func(head, name, phone) # Построение структуре поэлементно
|
||
return head # Возвращает финальную структуру
|
||
|
||
# Основная функция для запуска одного эксперимента
|
||
def run_one_experiment(records_shuffled, records_sorted, find_names, delete_names):
|
||
results = []
|
||
for mode, recs in [("shuffled", records_shuffled), ("sorted", records_sorted)]:
|
||
for name, build_fn, find_fn, delete_fn in STRUCTURES:
|
||
init_val = None if name in ("LinkedList", "BST") else [None] * 10007
|
||
head, t_insert = measure_time(build_and_measure, build_fn, recs, init_val)
|
||
|
||
# Создаем функции для поиска и удаления с фиксированными параметрами
|
||
def search_fn():
|
||
return [find_fn(head, n) for n in find_names]
|
||
|
||
def delete_fn_wrapper():
|
||
return [delete_fn(head, n) for n in delete_names]
|
||
|
||
t_find = measure_time(search_fn)[1]
|
||
t_delete = measure_time(delete_fn_wrapper)[1]
|
||
|
||
results += [
|
||
[name, mode, "insert", t_insert],
|
||
[name, mode, "find", t_find],
|
||
[name, mode, "delete", t_delete],
|
||
]
|
||
return results
|
||
|
||
# Генерация исходных данных
|
||
records_shuffled, records_sorted = generate_records(N)
|
||
|
||
# Подготовка списков имен для поиска и удаления
|
||
find_names = prepare_find_names(records_sorted)
|
||
delete_names = prepare_delete_names(records_sorted)
|
||
|
||
# Заголовки результатов
|
||
results = [["Запуск", "Структура", "Режим", "Операция", "Время (сек)"]]
|
||
|
||
# Проведение серии запусков
|
||
for run in range(1, REPEATS+1):
|
||
print(f"Запуск эксперимента: {run}")
|
||
one_run_results = run_one_experiment(records_shuffled, records_sorted, find_names, delete_names)
|
||
for struct, mode, op, t in one_run_results:
|
||
results.append([run, struct, mode, op, t]) # Добавляем результаты каждого запуска
|
||
|
||
# Подсчет средних значений по результатам
|
||
groups = {}
|
||
for row in results[1:]:
|
||
key = tuple(row[1:4]) # Ключ — название структуры, режим, тип операции
|
||
groups.setdefault(key, []).append(row[4]) # Собираем времена для среднего
|
||
|
||
for key, times in groups.items():
|
||
avg_time = sum(times)/len(times)
|
||
results.append(["average"] + list(key) + [avg_time]) # Средний результат
|
||
|
||
# Запись итоговых данных в CSV файл
|
||
with open("results.csv", "w", newline="", encoding="utf-8") as f:
|
||
writer = csv.writer(f)
|
||
writer.writerows(results)
|
||
|
||
print("Результаты сохранены") |