2026-rff_mp/semyanovra/scr/generate_data.py
2026-04-08 22:01:28 +03:00

110 lines
6.0 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.

"""
Экспериментальная часть. Пункт 1: Генерация тестовых данных.
Цель: создать список записей (имя, телефон) для дальнейшего тестирования
структур данных (связный список, хеш-таблица, BST).
Особенности реализации:
- N = 10000 записей.
- Два режима: случайный порядок и отсортированный по имени.
- Имена генерируются равномерно (User_00000 ... User_09999) + небольшой
набор повторяющихся имен для создания коллизий в хеш-таблице.
- Телефоны — случайные строки из 10 цифр.
"""
import random
def generate_test_data(n=10000, duplicate_names_ratio=0.1):
"""
Генерирует два набора записей: в случайном порядке и отсортированном.
Параметры:
- n: общее количество записей (по умолчанию 10000).
- duplicate_names_ratio: доля имен, которые будут повторяться (коллизии).
Например, 0.1 означает, что 10% записей будут использовать
имена из небольшого пула, остальные 90% — уникальные User_XXXXX.
Возвращает:
- records_shuffled: список кортежей (name, phone) в случайном порядке.
- records_sorted: тот же список, но отсортированный по имени.
"""
# 1. Создаем пул уникальных имен (равномерное распределение)
# Формат: User_00000, User_00001, ..., User_09999
unique_names = [f"User_{i:05d}" for i in range(n)]
# 2. Создаем небольшой пул имен для повторений (коллизий)
# Например, 20 разных имен, которые будут многократно встречаться.
collision_pool_size = max(1, int(n * duplicate_names_ratio)) # ~1000 имен для 10000 записей (10%)
collision_names = [f"Common_{j:03d}" for j in range(collision_pool_size)]
# 3. Формируем итоговый список имен с повторениями
# - Первые (n - collision_pool_size) записей — уникальные.
# - Оставшиеся collision_pool_size записей — случайные из пула коллизий.
names = []
# Уникальная часть
names.extend(unique_names[:n - collision_pool_size])
# Часть с повторениями (для проверки коллизий в хеш-таблице)
for _ in range(collision_pool_size):
names.append(random.choice(collision_names))
# Перемешиваем имена, чтобы повторяющиеся имена не шли подряд
random.shuffle(names)
# 4. Генерируем случайные телефоны (10 цифр)
phones = []
for _ in range(n):
phone = ''.join(random.choices('0123456789', k=10))
phones.append(phone)
# 5. Собираем записи в список кортежей
records = list(zip(names, phones))
# 6. Создаем две версии: случайную и отсортированную
records_shuffled = records.copy() # уже случайный порядок после shuffle
records_sorted = sorted(records, key=lambda x: x[0]) # сортировка по имени
return records_shuffled, records_sorted
def print_sample(records, title, count=10):
"""Вспомогательная функция: печатает первые count записей."""
print(f"\n{title} (первые {count} записей):")
for name, phone in records[:count]:
print(f" {name}: {phone}")
# ========== Демонстрация работы ==========
if __name__ == "__main__":
# Фиксируем seed для воспроизводимости результатов
random.seed(42)
# Генерируем данные: N = 10000, доля коллизий 10%
N = 10000
shuffled, sorted_data = generate_test_data(N, duplicate_names_ratio=0.1)
# Выводим статистику и примеры
print(f"Сгенерировано {N} записей.")
print(f"Доля имен с повторениями (коллизиями): ~10%")
# Показываем несколько примеров из каждого набора
print_sample(shuffled, "Случайный порядок")
print_sample(sorted_data, "Отсортированный порядок")
# Дополнительно: проверка, что в отсортированном порядке имена действительно упорядочены
first_five_sorted = [name for name, _ in sorted_data[:5]]
print(f"\nПервые 5 имен в отсортированном наборе: {first_five_sorted}")
# Ожидается: ['Common_000', 'Common_001', ...] или 'User_...' — лексикографически
# Проверка наличия коллизий (повторяющихся имен)
unique_names_in_shuffled = set(name for name, _ in shuffled)
print(f"\nУникальных имен в случайном наборе: {len(unique_names_in_shuffled)}")
print(f"(меньше {N} из-за повторений для коллизий)")
# Сохраняем в файлы (опционально, для отладки)
# import csv
# with open("docs/data/records_shuffled.csv", "w") as f:
# writer = csv.writer(f)
# writer.writerows(shuffled)
# with open("docs/data/records_sorted.csv", "w") as f:
# writer = csv.writer(f)
# writer.writerows(sorted_data)