Найкращий спосіб посіяти N незалежних генераторів випадкових чисел з 1 значення


10

У моїй програмі мені потрібно запустити N окремих потоків, кожен з яких має власний RNG, який використовується для вибірки великого набору даних. Мені потрібно мати можливість зафіксувати весь цей процес одним значенням, щоб я міг відтворити результати.

Чи достатньо просто послідовно збільшувати насіння для кожного показника?

В даний час я використовую numpy's, RandomStateякий використовує генератор псевдовипадкових чисел Mersenne Twister.

Фрагмент коду нижче:

# If a random number generator seed exists
if self.random_generator_seed:
    # Create a new random number generator for this instance based on its
    # own index
    self.random_generator_seed += instance_index
    self.random_number_generator = RandomState(self.random_generator_seed)

По суті я починаю з введеного користувачем насіння (якщо воно існує), і для кожного примірника / потоку послідовно додаю індекс (від 0 до N-1) запущеного екземпляра. Я не знаю, чи це хороша практика, чи є кращий спосіб зробити це.


1
Чи знаєте ви заздалегідь, скільки псевдовипадкових значень використовуватиме кожен потік - чи принаймні ви можете отримати хорошу верхню межу?
whuber

Ні я не можу. Він відбирає регіони, які підсумовуються до досягнення порогу. Розміри регіонів можуть суттєво відрізнятися.
EricR

Відповіді:


9

Це, звичайно, не велика практика. Наприклад, розгляньте, що відбувається, коли ви робите два запуски з кореневими насінням 12345 та 12346. Кожен запуск матиме N-1спільні потоки.

Реалізації Mersenne Twister (включаючи numpy.randomта random) зазвичай використовують інший PRNG для розширення цілого насіння в великий вектор стану (624 32-бітні цілі числа), який використовує MT; це масив з RandomState.get_state(). Хороший спосіб зробити те, що ви хочете, - запустити цей PRNG, посіяний цілим вхідним числом один раз, і отримати N*62432-бітні цілі числа з нього. Розділіть цей потік на Nвектори стану та використовуйте RandomState.set_state()для явної ініціалізації кожного RandomStateекземпляра. Вам, можливо, доведеться проконсультуватися з джерелами С numpy.randomабо _randomзі стандартної бібліотеки, щоб отримати PRNG (вони однакові). Я не впевнений, чи хтось реалізував окрему версію PRNG для Python.


Я думаю, що це може бути найкращим рішенням, яке я чув досі. Я не думаю, що це має велике значення в тому, як я розділив потік вгору, хоча правильно? Здається, набагато навряд чи мати повторювану послідовність на 624 32-бітних цілих числах між екземплярами, незалежно від того, як вони вибираються з початкового PRNG та початкового.
EricR

1
Насправді я трохи пройдуся назад. Мені не зрозуміло, що ініціалізатор PRNG розроблений так, щоб з нього виводили довільно багато значень. Розглянемо використання іншого якісного PRNG (бажано не пов'язаного з MT) для генерації потоку стану. Можна реалізувати HMAC-DRBG (PRNG, використовуючи HMAC як криптографічний примітив), використовуючи лише стандартну бібліотеку порівняно прямо. Криптографічна безпека не викликає занепокоєння; просто простота реалізації та якість бітового потоку. Вам потрібно буде забезпечити, щоб не було зроблено жодних векторів на всі нулі, за дуже рідкого випадкового випадку.
Роберт Керн

Або просто використовувати одну з нових RandomStateреалізацій в розробці, яка використовує алгоритм, який має встановлені потоки. Тобто, ви ініціалізуєте кожен RandomStateекземпляр з одним і тим самим насіннєвим і різними ідентифікаторами потоку (просто збільшений тон), і вам гарантовано незалежні потоки. pypi.python.org/pypi/randomstate
Роберт Керн

4

Рішення, яке використовується при паралельній обробці, полягає у використанні вашого випадкового генератора , де - ваше насіння, шляхом -бої:Φ(u)uN

  1. генеруватиΦ(u),ΦN(u),Φ2N(u),...
  2. генеруватиΦ2(u),Φ1+N(u),Φ1+2N(u),...
  3. ...
  4. генеруватиΦN1(u),ΦN1+N(u),ΦN1+2N(u),...

де . Таким чином ви використовуєте одне насіння, і ваші послідовності є рівномірними та незалежними.Φn(u)=Φ(Φn1(u))


2

Зараз існує пакет Python під назвою RandomGen, який має методи для досягнення цього.

Він підтримує незалежні потоки, створені з одного насіння, а також протокол стрибків для старших генераторів випадкових чисел, таких як MT19937.


0

Деякі люди стверджують, що існують кореляції у випадкових числах, породжених послідовними насінням. /programming/10900852/near-seeds-in-random-number-generation-may-give-s подобни-random- numbers Я не впевнений, наскільки це правда.

Якщо ви переживаєте з цього приводу, чому б не використати генератор одного випадкового числа, щоб вибрати насіння для всіх інших генераторів?


Просто тому, що я не хочу мати шансів випадково генерувати одне і те ж насіння для більш ніж одного генератора. Звичайно, я міг би виконати деякі програми програмування, щоб не допустити цього, але тоді я не знаю, як це було б краще, ніж збирати насіння в першу чергу.
EricR

1
Мабуть , кореляція можлива з послідовними насінням ... Однак, як показано у статті, пов’язаній із відповіддю із блогу Джона Д Кука, використання однієї RNG для генерування насіння для інших генераторів набагато гірше, адже ви стикаєтесь із проблемою дня народження! У ній сказано, що генеруючи 1000 16-бітових неподписаних насіння випадковим чином є 99,95% шансу перекритись!
Praveen
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.