Несколько независимых потоков случайных чисел из одного семени - PullRequest
0 голосов
/ 02 ноября 2018

У меня есть n аналогичные анализы, каждый из которых использует m_i потоки псевдослучайных чисел (m_i может варьироваться в зависимости от анализа). Каждый анализ имеет свое собственное начальное число случайных чисел, так что случайные числа не связаны между анализами.

Моя проблема в том, что мне нужно создать m_i потоки из одного семени. Анализ в настоящее время написан на Numpy, так что решения его Mersenne Twister идеальны, но я открыт для решений в других зрелых библиотеках. Я рассмотрел эти возможности:

  1. Используйте начальное число для создания потока случайных чисел, нарисуйте m_i целые числа и используйте эти целые числа в качестве начальных чисел для m_i случайных потоков. Это не хорошо из-за парадокс дня рождения . Есть 2 ^ 32 (~ 4 миллиарда) семян, но если я получу столкновение (два потока начались с одного и того же семени) после 2 ^ 16 (~ 60000).

  2. Умножьте начальное число на некоторую константу m_max для каждого индекса потока на 1, чтобы получить начальное значение этого потока. (например, с seed=2 и m_max=10000, анализ будет использовать начальные значения 20001 , 20002, 20003 и др.). Это нежелательно, поскольку все анализы будут ограничены m_max потоками, прежде чем возникнут коллизии, а если m_max слишком велико, количество анализов будет ограничено 2^32/m_max.

  3. Используйте начальное число для создания потока случайных чисел, нарисуйте 624 32-битные целые числа на каждый необходимый поток и установите состояние каждого потока в 624 целых числа, нарисованных для него. Это кажется идеальным, за исключением того, что я понятия не имею, действительно ли 624 случайных целых числа являются действительным внутренним состоянием для твистера Мерсенна (это могут быть произвольные биты?). Я также не знаю, есть ли какая-то скрытая корреляция между целыми числами (возможно, это один и тот же поток, только смещенный на 624).

Есть ли стандартный способ сделать это?

1 Ответ

0 голосов
/ 02 ноября 2018

Подход 3 может работать, так как начальное число для любого PRNG может быть таким же, как и состояние этого PRNG (например, Mersenne Twister имеет длину состояния 19968 битов или 624 * 32 битов, поэтому может принимать начальное число до столько битов - это не ограничено 32 или 64 битами, как это практикуется со многими API, которые реализуют Mersenne Twister). Однако вы должны использовать PRNG несвязанного дизайна с Mersenne Twister, такой как PCG, чтобы посеять этот PRNG, а затем вытянуть целое число 624, как вы предлагаете. (Или, если вам не требуются воспроизводимые результаты, или если вы сохраните 624-целые начальные числа, сгенерированные таким образом, вы можете использовать криптографический ГСЧ, такой как os.urandom() или secrets.SystemRandom, для рисования этих начальных чисел.) Моя статья о RNG предлагает несколько PRNG с различным дизайном.

...