Документация Python неофициальный перевод

9.6. random – Генерация псевдослучайных чиселrandom – Generate pseudo-random numbers

Исходный код: Lib/random.py


Этот модуль реализует генераторы псевдослучайных чисел для различных распределений.

Для целых чисел – равномерный выбор из диапазона. Для последовательностей – равномерный выбор случайного элемента, функция для генерации случайной перестановки списка на месте и функция для случайной выборки без возвращения.

На вещественной прямой есть функции для вычисления равномерного, нормального (гауссовского), логнормального, отрицательного экспоненциального, гамма и бета распределений. Для генерации распределений углов доступно распределение фон Мизеса.

Почти все функции модуля зависят от базовой функции random(), которая генерирует случайное число с плавающей запятой, равномерно распределённое в полуоткрытом диапазоне [0.0, 1.0). Python использует вихрь Мерсенна в качестве основного генератора. Он выдаёт числа с плавающей запятой точностью 53 бита и имеет период 2**19937-1. Базовая реализация на C быстра и потокобезопасна. Вихрь Мерсенна – один из наиболее тщательно протестированных генераторов случайных чисел. Однако, будучи полностью детерминированным, он не подходит для всех целей и совершенно непригоден для криптографии.

Функции, предоставляемые этим модулем, на самом деле являются привязанными методами скрытого экземпляра класса random.Random. Можно создать собственные экземпляры Random, чтобы получить генераторы, не разделяющие состояние. Это особенно полезно в многопоточных программах: создайте отдельный экземпляр Random для каждого потока и используйте метод jumpahead(), чтобы сгенерированные последовательности в разных потоках с высокой вероятностью не пересекались.

Класс Random также можно наследовать, если требуется использовать другой базовый генератор собственной разработки: в этом случае переопределите методы random(), seed(), getstate(), setstate() и jumpahead(). При необходимости новый генератор может предоставить метод getrandbits() – это позволяет randrange() выполнять выборку из произвольно большого диапазона.

Новое в версии 2.4: метод getrandbits().

В качестве примера наследования модуль random предоставляет класс WichmannHill, который реализует альтернативный генератор на чистом Python. Этот класс предоставляет обратно совместимый способ воспроизведения результатов из более ранних версий Python, в которых алгоритм Wichmann-Hill использовался в качестве основного генератора. Обратите внимание, что этот генератор Wichmann-Hill больше не рекомендуется к использованию: его период слишком мал по современным меркам, и известно, что генерируемая последовательность не проходит некоторые строгие тесты на случайность. См. ссылки ниже для ознакомления с недавним вариантом, который исправляет эти недостатки.

Изменено в версии 2.3: MersenneTwister заменил Wichmann-Hill в качестве генератора по умолчанию.

Модуль random также предоставляет класс SystemRandom, который использует системную функцию os.urandom() для генерации случайных чисел из источников, предоставляемых операционной системой.

Предупреждение

Псевдослучайные генераторы этого модуля не следует использовать в целях безопасности. Используйте os.urandom() или SystemRandom, если требуется криптографически стойкий генератор псевдослучайных чисел.

Функции учёта:

random.seed(a=None)

Инициализирует внутреннее состояние генератора случайных чисел.

Вызов None или вызов без аргумента инициализирует генератор от текущего времени или от источника случайности операционной системы, если он доступен (подробнее о доступности см. функцию os.urandom()).

Если a не является None, int или long, то вместо него используется hash(a). Обратите внимание, что хеш-значения для некоторых типов недетерминированы, когда включено PYTHONHASHSEED.

Изменено в версии 2.4: ранее ресурсы операционной системы не использовались.

random.getstate()

Возвращает объект, фиксирующий текущее внутреннее состояние генератора. Этот объект можно передать в setstate() для восстановления состояния.

Новое в версии 2.1.

Изменено в версии 2.6: значения состояния, созданные в Python 2.6, нельзя загрузить в более ранние версии.

random.setstate(state)

state должен быть получен из предыдущего вызова getstate(), а setstate() восстанавливает внутреннее состояние генератора в то, которое было на момент вызова getstate().

Новое в версии 2.1.

random.jumpahead(n)

Изменяет внутреннее состояние на другое, с высокой вероятностью далёкое от текущего. n – неотрицательное целое число, используемое для перемешивания текущего вектора состояния. Это наиболее полезно в многопоточных программах в сочетании с несколькими экземплярами класса Random: setstate() или seed() можно использовать для приведения всех экземпляров к одному внутреннему состоянию, а затем jumpahead() – для разнесения состояний экземпляров на большое расстояние.

Новое в версии 2.1.

Изменено в версии 2.3: Вместо перехода к конкретному состоянию через n шагов вперёд, jumpahead(n) переходит к другому состоянию, которое, вероятно, отделено многими шагами.

random.getrandbits(k)

Возвращает целое число long Python с k случайными битами. Этот метод предоставляется генератором MersenneTwister; некоторые другие генераторы также могут предоставлять его как опциональную часть API. Когда доступен, getrandbits() позволяет randrange() работать с произвольно большими диапазонами.

Новое в версии 2.4.

Функции для целых чисел:

random.randrange(stop)
random.randrange(start, stop[, step])

Возвращает случайно выбранный элемент из range(start, stop, step). Это равнозначно choice(range(start, stop, step)), но на самом деле не создаёт объект range.

Новое в версии 1.5.2.

random.randint(a, b)

Возвращает случайное целое число N, такое что a <= N <= b.

Функции для последовательностей:

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. Используется для случайной выборки без возвращения.

Новое в версии 2.3.

Возвращает новый список, содержащий элементы из population, не изменяя исходную population. Результирующий список упорядочен по порядку выбора, так что все подсписки также будут корректными случайными выборками. Это позволяет разделить победителей розыгрыша (выборку) на обладателей главного и второго призов (подсписки).

Элементы population не обязаны быть хэшируемыми или уникальными. Если population содержит повторения, то каждое вхождение является возможным элементом выборки.

Чтобы выбрать выборку из диапазона целых чисел, используйте объект xrange() в качестве аргумента. Это особенно быстро и эффективно по памяти для выборки из большой совокупности: sample(xrange(10000000), 60).

Следующие функции генерируют конкретные вещественные распределения. Имена параметров функций соответствуют переменным в уравнении распределения, как принято в математической практике; большинство этих уравнений можно найти в любом учебнике по статистике.

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 и с заданной модой между этими границами. Границы low и high по умолчанию равны нулю и единице. Аргумент mode по умолчанию равен середине между границами, что даёт симметричное распределение.

Новое в версии 2.6.

random.betavariate(alpha, beta)

Бета-распределение. Условия на параметры: alpha > 0 и beta > 0. Возвращаемые значения находятся в диапазоне от 0 до 1.

random.expovariate(lambd)

Экспоненциальное распределение. lambd – это 1.0, делённая на желаемое среднее. Оно должно быть ненулевым. (Параметр мог бы называться «lambda», но это зарезервированное слово в 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.WichmannHill([seed])

Класс, реализующий алгоритм Вичмана-Хилла в качестве основного генератора. Имеет все те же методы, что и Random, а также метод whseed(), описанный ниже. Поскольку этот класс реализован на чистом Python, он не является потокобезопасным и может требовать блокировок между вызовами. Период генератора составляет 6 953 607 871 644, что достаточно мало, и требуется соблюдать осторожность, чтобы две независимые случайные последовательности не перекрывались.

random.whseed([x])

Это устарело, предоставляется для побитовой совместимости с версиями Python до 2.1. Подробнее см. seed(). whseed() не гарантирует, что разные целочисленные аргументы приводят к различным внутренним состояниям, и в общей сложности может давать не более чем около 2**24 различных внутренних состояний.

class random.SystemRandom([seed])

Класс, использующий функцию os.urandom() для генерации случайных чисел из источников, предоставляемых операционной системой. Доступен не на всех системах. Не полагается на состояние программного обеспечения, и последовательности не воспроизводимы. Соответственно, методы seed() и jumpahead() не действуют и игнорируются. Методы getstate() и setstate() при вызове вызывают NotImplementedError.

Новое в версии 2.4.

Примеры базового использования:

>>> random.random()        # Случайный float x, 0.0 <= x < 1.0
0.37444887175646646
>>> random.uniform(1, 10)  # Случайный float x, 1.0 <= x < 10.0
1.1800146073117523
>>> random.randint(1, 10)  # Целое число от 1 до 10 включительно
7
>>> random.randrange(0, 101, 2)  # Чётное целое число от 0 до 100
26
>>> random.choice('abcdefghij')  # Выбрать случайный элемент
'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)  # Выбрать 3 элемента
[4, 1, 5]

См. также

М. Мацумото и Т. Нисимура, «Вихрь Мерсенна: 623-мерно равномерно распределенный генератор псевдослучайных чисел», ACM Transactions on Modeling and Computer Simulation том 8, № 1, январь, стр. 3–30, 1998.

Wichmann, B. A. & Hill, I. D., “Algorithm AS 183: An efficient and portable pseudo-random number generator”, Applied Statistics 31 (1982) 188-190.

Complementary-Multiply-with-Carry recipe для совместимого альтернативного генератора случайных чисел с длинным периодом и сравнительно простыми операциями обновления.