Найкращий спосіб посіяти 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),Φ2∗N(u),...
  2. генеруватиΦ2(u),Φ1+N(u),Φ1+2∗N(u),...
  3. ...
  4. генеруватиΦN−1(u),ΦN−1+N(u),ΦN−1+2∗N(u),...

де . Таким чином ви використовуєте одне насіння, і ваші послідовності є рівномірними та незалежними.Φn(u)=Φ(Φn−1(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.