#python #numpy #random
#python #numpy #Случайный
Вопрос:
Я хочу сгенерировать несколько потоков случайных чисел в python. Я пишу программу для моделирования системы очередей и хочу, чтобы один поток соответствовал времени прибытия, а другой — времени обслуживания и так далее.
numpy.random()
генерирует случайные числа из глобального потока.
В matlab есть нечто, называемое RandStream, которое позволяет мне создавать несколько потоков.
Есть ли какой-нибудь способ создать что-то вроде RandStream в Python
Комментарии:
1. Вы собираетесь использовать это для уменьшения дисперсии?
Ответ №1:
Как Numpy, так и внутренние генераторы случайных чисел имеют создаваемые экземпляры классов.
Для просто random
:
import random
random_generator = random.Random()
random_generator.random()
#>>> 0.9493959884174072
И для Numpy:
import numpy
random_generator = numpy.random.RandomState()
random_generator.uniform(0, 1, 10)
#>>> array([ 0.98992857, 0.83503764, 0.00337241, 0.76597264, 0.61333436,
#>>> 0.0916262 , 0.52129459, 0.44857548, 0.86692693, 0.21150068])
Комментарии:
1. Где мне найти документы для первого? Кажется, я не могу правильно использовать Google…
2. @Atcold «Функции, предоставляемые этим модулем, на самом деле являются связанными методами скрытого экземпляра
random.Random
класса. Вы можете создавать свои собственные экземплярыRandom
, чтобы получить генераторы, которые не разделяют состояние «. — docs.python.org/3/library/random.html3. Но как вы генерируете независимые потоки? Гарантированно ли работают последовательные начальные значения?
4. @RafaelAlmeida Это патологический пример, и есть несколько причин, по которым это здесь не применимо. 1) мы генерируем только две последовательности, поэтому последовательности будут быстро декоррелироваться, а не одну выборку из многих смежных последовательностей, 2) В Python seeding есть шаг хеширования для исправления корреляций, 3) вы все равно никогда не получите идеальной независимости от посредственного генератора, такого как Mersenne Twister; используйтелучший RNG (желательно криптографический) и не используйте фиксированные начальные значения, если это проблема. Я согласен с тем, что использование больших начальных значений с более высокой энтропией более рискованно.
5. @RafaelAlmeida Стоит отметить, что C #, похоже, использует генератор вычитания, который выглядит мусором.
Ответ №2:
Вам не нужно использовать пакет RandomGen. Достаточно просто инициировать два потока. Например:
import numpy as np
prng1 = np.random.RandomState()
prng2 = np.random.RandomState()
prng1.seed(1)
prng2.seed(1)
Теперь, если вы используете оба потока prngX.rand()
, вы обнаружите, что два потока дадут вам идентичные результаты, что означает, что они являются независимыми потоками с одинаковым начальным значением.
Чтобы использовать random
пакет, просто замените np.random.RandomState()
на random.Random()
.
Ответ №3:
Для обеспечения воспроизводимости вы можете передать начальное значение непосредственно в random.Random()
, а затем вызвать переменные оттуда. Затем каждый инициированный экземпляр будет выполняться независимо от другого. Например, если вы запустите:
import random
rg1 = random.Random(1)
rg2 = random.Random(2)
rg3 = random.Random(1)
for i in range(5): print(rg1.random())
print('')
for i in range(5): print(rg2.random())
print('')
for i in range(5): print(rg3.random())
Вы получите:
0.134364244112
0.847433736937
0.763774618977
0.255069025739
0.495435087092
0.956034271889
0.947827487059
0.0565513677268
0.0848719951589
0.835498878129
0.134364244112
0.847433736937
0.763774618977
0.255069025739
0.495435087092
Ответ №4:
В ответе Veedrac не было указано, как можно генерировать независимые потоки.
Лучший способ, который я смог найти для генерации независимых потоков, — это использовать замену для RandomState numpy. Это обеспечивается пакетом RandomGen.
Он поддерживает независимые случайные потоки, но они используют один из трех генераторов случайных чисел: PCG64, ThreeFry или Philox. Если вы хотите использовать более традиционный MT19937, вы можете вместо этого полагаться на jumping .
Комментарии:
1.
random.Random()
является независимым потоком, по крайней мере, до пределов твистера Мерсенна. Если вам нужныn
потоки, сделайте[random.Random() for _ in range(n)]
.
Ответ №5:
numpy
добавлена возможность генерировать независимые потоки случайных чисел с использованием SeedSequence
. Это обрабатывает предоставленное пользователем начальное значение, обычно в виде целого числа некоторого размера, и преобразует его в начальное состояние для BitGenerator. Он использует методы хеширования, чтобы гарантировать, что низкокачественные начальные состояния превращаются в высококачественные начальные состояния (по крайней мере, с очень высокой вероятностью).
from numpy.random import SeedSequence, default_rng
ss = SeedSequence(12345)
# Spawn off 10 child SeedSequences to pass to child processes.
child_seeds = ss.spawn(10)
streams = [default_rng(s) for s in child_seeds]
каждый поток является генератором PCG64. Случайные числа могут генерироваться последовательно следующим образом —
for i in 1:K
instance[i] = [s.uniform() for s in streams]
Есть и другие способы генерировать независимые потоки случайных чисел, проверьте numpydocs .