random — Генерация псевдослучайных чисел
Исходный код: Lib/random.py
Этот модуль реализует генераторы псевдослучайных чисел для различных распределений.
Для целых чисел происходит равномерный выбор из диапазона. Для последовательностей есть равномерный выбор случайного элемента, функция для генерации случайной перестановки списка на месте и функция для случайного отбора без повторений.
На вещественной оси есть функции для вычисления равномерного, нормального (гауссовского), логнормального, отрицательно экспоненциального, гамма и бета распределений. Для генерации распределений углов доступно распределение Винера.
Практически все функции модуля зависят от базовой функции random(), которая генерирует случайное вещественное число равномерно в полуоткрытом интервале [0.0, 1.0). Python использует Мерсенн Твистер в качестве основного генератора. Он производит плавающие числа с точностью 53 бита и имеет период 219937-1. Базовая реализация на C быстрая и потокобезопасна. Генератор Мерсенна Твистера является одним из самых широко протестированных генераторов псевдослучайных чисел. Однако, будучи полностью детерминированным, он не подходит для всех целей и совершенно непригоден для криптографических целей.
Функции, предоставляемые этим модулем, на самом деле являются методами объекта скрытого экземпляра класса random.Random. Вы можете создать собственные экземпляры класса Random для получения генераторов, которые не разделяют состояние.
Класс Random также можно наследовать, если вы хотите использовать другой базовый генератор по своему усмотрению: в этом случае переопределите методы random(), seed(), getstate(), и setstate(). Дополнительно, новый генератор может предоставить метод getrandbits() — это позволяет randrange() выполнять выбор в произвольном большом диапазоне.
Модуль random также предоставляет класс SystemRandom, который использует системную функцию os.urandom() для генерации случайных чисел из источников, предоставляемых операционной системой.
Предупреждение
Генераторы псевдослучайных чисел этого модуля не должны использоваться в целях безопасности.
Функции для ведения учета:
-
random.seed(a=None, version=2) -
Инициализация генератора псевдослучайных чисел.
Если a опущено или
None, используется текущее системное время. Если источники случайности предоставляются операционной системой, они используются вместо системного времени (см. функциюos.urandom()для получения подробностей о доступности).Если a — целое число, оно используется непосредственно.
С версией 2 (по умолчанию), строка, байтовая последовательность или объект bytearray преобразуются в целое число и все его биты используются.
С версией 1 (предоставленной для воспроизведения случайных последовательностей из старых версий Python), алгоритм для строк и байтовых последовательностей генерирует более узкий диапазон семян.
Изменено в версии 3.2: Переход на схему версии 2, которая использует все биты в строке-семени.
-
random.getstate() -
Возвращает объект, сохраняющий текущее внутреннее состояние генератора. Этот объект можно передать в
setstate()для восстановления состояния.
-
random.setstate(state) -
state должен был быть получен из предыдущего вызова
getstate(), аsetstate()восстанавливает внутреннее состояние генератора в то состояние, которое существовало во время вызоваgetstate().
-
random.getrandbits(k) -
Возвращает целое число Python с k случайными битами. Этот метод поставляется с генератором Мерсенн Твистер, и некоторые другие генераторы также могут предоставлять его как дополнительную часть API. При наличии
getrandbits()позволяетrandrange()обрабатывать произвольно большие диапазоны.
Функции для целых чисел:
-
random.randrange(stop) -
random.randrange(start, stop[, step]) -
Возвращает случайно выбранный элемент из
range(start, stop, step). Это эквивалентноchoice(range(start, stop, step)), но фактически не создает объект диапазона.Шаблон позиционных аргументов соответствует шаблону
range(). Не следует использовать ключевые аргументы, так как функция может использовать их неожиданным образом.Изменено в версии 3.2:
randrange()более совершенным образом генерирует равномерно распределённые значения. Раньше использовался стиль вродеint(random()*n), что могло приводить к немного неравномерному распределению.
-
random.randint(a, b) -
Возвращает случайное целое число N такое, что
a <= N <= b. Псевдоним дляrandrange(a, b+1).
Функции для последовательностей:
-
random.choice(seq) -
Возвращает случайный элемент из непустой последовательности seq. Если seq пустая, возбуждается исключение
IndexError.
-
random.shuffle(x[, random]) -
Перемешивает последовательность x на месте. Необязательный аргумент random — это функция без аргументов, возвращающая случайное вещественное число в интервале [0.0, 1.0); по умолчанию это функция
random().Обратите внимание, что для даже относительно небольших
len(x), общее число перестановок x больше периода большинства генераторов псевдослучайных чисел; это означает, что большинство перестановок длинной последовательности никогда не могут быть сгенерированы.
-
random.sample(population, k) -
Возвращает список длиной k из уникальных элементов, выбранных из последовательности или множества population. Используется для случайного отбора без повторений.
Возвращает новый список, содержащий элементы из исходной последовательности, не изменяя её. Результирующий список расположен в порядке выбора, так что все подсписки также будут являться корректными случайными выборками. Это позволяет разделить победителей розыгрыша (выборка) на победителей главного приза и призёров (подсписки).
Элементы последовательности population не обязательно должны быть хэшируемыми или уникальными. Если последовательность population содержит повторения, то каждое повторение является возможным элементом в выборке.
Для выбора выборки из диапазона целых чисел используйте объект
range()в качестве аргумента. Это особенно быстро и экономит память при выборке из большой генерации:sample(range(10000000), 60).Если размер выборки больше размера исходной последовательности, возбуждается исключение
ValueError.
Следующие функции генерируют конкретные вещественные распределения. Параметры функций названы в соответствии с соответствующими переменными в уравнении распределения, используемыми в обычной математической практике; большинство этих уравнений можно найти в любом учебнике по статистике.
-
random.random() -
Возвращает следующее случайное число с плавающей точкой в диапазоне [0.0, 1.0).
-
random.uniform(a, b) -
Возвращает случайное число с плавающей точкой N такое, что
a <= N <= bдляa <= bиb <= N <= aдляb < a.Конечное значение
bможет или не может быть включено в диапазон в зависимости от округления с плавающей точкой в уравненииa + (b-a) * random().
-
random.triangular(low, high, mode) -
Возвращает случайное число с плавающей точкой N такое, что
low <= N <= highи с заданным mode между этими границами. Границы low и high по умолчанию равны нулю и единице. Аргумент mode по умолчанию равен середине между границами, что даёт симметричное распределение.
-
random.betavariate(alpha, beta) -
Бета-распределение. Условия на параметры —
alpha > 0иbeta > 0. Возвращаемые значения находятся в диапазоне от 0 до 1.
-
random.expovariate(lambd) -
Экспоненциальное распределение. lambd равно 1,0, делённому на желаемое среднее значение. Оно должно быть отличным от нуля. (Параметр назывался бы «лямбда», но это зарезервированное слово в Python.) Возвращаемые значения находятся в диапазоне от 0 до плюс бесконечности, если lambd положительно, и от минус бесконечности до 0, если lambd отрицательно.
-
random.gammavariate(alpha, beta) -
Гамма-распределение. (Не функция гамма!) Условия на параметры —
alpha > 0иbeta > 0.Функция плотности вероятности:
x ** (alpha - 1) * math.exp(-x / beta) pdf(x) = -------------------------------------- math.gamma(alpha) * beta ** alpha
-
random.gauss(mu, sigma) -
Распределение Гаусса. mu — среднее значение, а sigma — стандартное отклонение. Это немного быстрее, чем функция
normalvariate(), определённая ниже.
-
random.lognormvariate(mu, sigma) -
Логарифмически нормальное распределение. Если взять натуральный логарифм от этого распределения, получится нормальное распределение со средним значением mu и стандартным отклонением sigma. mu может иметь любое значение, а sigma должно быть больше нуля.
-
random.normalvariate(mu, sigma) -
Нормальное распределение. mu — среднее значение, а sigma — стандартное отклонение.
-
random.vonmisesvariate(mu, kappa) -
mu — средний угол, выраженный в радианах между 0 и 2*pi, а kappa — параметр концентрации, который должен быть больше или равен нулю. Если kappa равно нулю, это распределение сводится к равномерному случайному углу в диапазоне от 0 до 2*pi.
-
random.paretovariate(alpha) -
Распределение Парето. alpha — параметр формы.
-
random.weibullvariate(alpha, beta) -
Распределение Вейбулла. alpha — параметр масштаба, а beta — параметр формы.
Альтернативный генератор:
-
class random.SystemRandom([seed]) -
Класс, использующий функцию
os.urandom()для генерации случайных чисел из источников, предоставляемых операционной системой. Не доступен на всех системах. Не полагается на состояние программного обеспечения, и последовательности не воспроизводимы. Соответственно, методseed()не оказывает влияния и игнорируется. Методыgetstate()иsetstate()генерируют исключениеNotImplementedError, если вызваны.
См. также
М. Мацумото и Т. Нисимура, «Mersenne Twister: A 623-dimensionally equidistributed uniform pseudorandom number generator», ACM Transactions on Modeling and Computer Simulation Vol. 8, No. 1, январь с.3–30 1998.
Рецепт Complementary-Multiply-with-Carry для совместимого альтернативного генератора случайных чисел с большим периодом и относительно простыми операциями обновления.
1. Примечания по воспроизводимости
Иногда полезно иметь возможность воспроизвести последовательности, созданные генератором псевдослучайных чисел. Используя одно и то же значение seed, последовательность должна воспроизводиться от запуска к запуску, пока не работают несколько потоков.
Большинство алгоритмов и функций инициализации модуля random могут меняться в разных версиях Python, но два аспекта гарантированно останутся неизменными:
- Если будет добавлен новый метод инициализации, то будет предложен обратный совместимый инициализатор.
- Метод
random()генератора будет продолжать генерировать одну и ту же последовательность, когда совместимый инициализатор получит тот же seed.
2. Примеры и рецепты
Базовое использование:
>>> random.random() # Random float x, 0.0 <= x < 1.0
0.37444887175646646
>>> random.uniform(1, 10) # Random float x, 1.0 <= x < 10.0
1.1800146073117523
>>> random.randrange(10) # Integer from 0 to 9
7
>>> random.randrange(0, 101, 2) # Even integer from 0 to 100
26
>>> random.choice('abcdefghij') # Single random element
'c'
>>> items = [1, 2, 3, 4, 5, 6, 7]
>>> random.shuffle(items)
>>> items
[7, 3, 2, 5, 6, 4, 1]
>>> random.sample([1, 2, 3, 4, 5], 3) # Three samples without replacement
[4, 1, 5]
Частая задача — сделать выбор random.choice() со взвешенными вероятностями.
Если веса — это небольшие целые отношения, простым способом является создание выборки с повторениями:
>>> weighted_choices = [('Red', 3), ('Blue', 2), ('Yellow', 1), ('Green', 4)]
>>> population = [val for val, cnt in weighted_choices for i in range(cnt)]
>>> population
['Red', 'Red', 'Red', 'Blue', 'Blue', 'Yellow', 'Green', 'Green', 'Green', 'Green']
>>> random.choice(population)
'Green'
Более общий подход заключается в составлении кумулятивного распределения весов с помощью itertools.accumulate(), а затем в поиске случайного значения с помощью bisect.bisect():
>>> choices, weights = zip(*weighted_choices) >>> cumdist = list(itertools.accumulate(weights)) >>> cumdist # [3, 3+2, 3+2+1, 3+2+1+4] [3, 5, 6, 10] >>> x = random.random() * cumdist[-1] >>> choices[bisect.bisect(cumdist, x)] 'Blue'
© 2001–2020 Python Software Foundation
Licensed under the PSF License.
https://docs.python.org/3.5/library/random.html