Для такого небольшого набора входов просто сгенерируйте все возможные выходы и sample
их:
import itertools
import random
size = 6
random.sample(list(itertools.product(range(size+1), repeat=2)), 5)
Вы указываете, что границы (size
) могут быть параметром, хотя и если границы могут быть даже немного больше, это может быть проблемой (вы будете генерировать size ** 2
tuple
s, чтобы выбрать 5
из них, и использование памяти может выйти из-под контроля). Если это проблема, поскольку вам нужна только пара целых чисел, есть дешевый трюк: выберите one случайное целое число, которое кодирует оба получаемых целых числа, а затем декодируйте его. Например:
size = 6
raw_sample = random.sample(range((size + 1) ** 2), 5)
decoded_sample = [divmod(x, size+1) for x in raw_sample)]
Поскольку range
не требует дополнительных затрат (использование памяти не зависит от длины), вы можете выбрать из него ровно пять значений, а служебные расходы будут пропорциональны выбранным пяти, а не 49 возможных результатов. Затем вы вычисляете частное и остаток на основе диапазона одного значения (от 0 до size
включительно в данном случае, поэтому size + 1
возможных значений), и это позволяет получить максимальные и минимальные результаты дешево.
Различия в производительности резко; сравнение:
def unique_random_pairs_by_product(size):
return random.sample(list(itertools.product(range(size+1), repeat=2)), 5)
с:
def unique_random_pairs_optimized(size):
val_range = size + 1
return [divmod(x, val_range) for x in random.sample(range(val_range * val_range), 5)]
версия optimized
занимает примерно на 15% меньше времени даже для аргумента 6
(~ 4,65 мкс для product
, ~ 3,95 мкс для optimized
). Но при size
из 6
вы вообще не видите коэффициент масштабирования. Для size=100
, optimized
увеличивается только до ~ 4,35 мкс (время немного увеличивается, потому что более крупный range
с большей вероятностью должен будет выделять новые int
с вместо использования небольшого кеша int
), в то время как product
скачок до 387 мкс, разница почти в 100 раз. А для size=1000
время для product
увеличивается до 63,8 мс, а optimized
остается ~ 4,35 мкс; разница в 10 000 раз во время выполнения (и еще более высокий коэффициент использования памяти). Если size
становится больше этого значения, решение на основе product
быстро достигнет точки, когда задержка даже из одной выборки будет заметна для человека; optimized
решение будет продолжать работать с идентичной производительностью (по модулю невероятно крошечные различия в стоимости divmod
).