En mi programa, necesito ejecutar N subprocesos separados, cada uno con su propio RNG, que se utiliza para muestrear un gran conjunto de datos. Necesito poder sembrar todo este proceso con un solo valor para poder reproducir los resultados.
¿Es suficiente simplemente aumentar secuencialmente la semilla para cada índice?
Actualmente uso numpy
's RandomState
que usa un generador de números pseudoaleatorio Mersenne Twister.
Fragmento de código a continuación:
# 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)
Básicamente, comienzo con una semilla introducida por el usuario (si existe) y para cada instancia / hilo agrego secuencialmente el índice (0 a N-1) de la instancia en ejecución. No sé si esta es una buena práctica o si hay una mejor manera de hacerlo.
Respuestas:
No es una buena práctica, ciertamente. Por ejemplo, considere lo que sucede cuando realiza dos ejecuciones con semillas raíz de 12345 y 12346. Cada ejecución tendrá
N-1
secuencias en común.Las implementaciones de Mersenne Twister (incluyendo
numpy.random
yrandom
) generalmente usan un PRNG diferente para expandir la semilla entera en el vector de estado grande (624 enteros de 32 bits) que utiliza MT; Esta es la matriz deRandomState.get_state()
. Una buena manera de hacer lo que quiere es ejecutar ese PRNG, sembrado con su entero de entrada una vez, y obtenerN*624
enteros de 32 bits. Divida esa secuencia enN
vectores de estado y úselaRandomState.set_state()
para inicializar explícitamente cadaRandomState
instancia. Puede que tenga que consultar las fuentes C de la biblioteca estándarnumpy.random
o_random
desde ella para obtener ese PRNG (son las mismas). No estoy seguro de si alguien ha implementado una versión independiente de ese PRNG para Python.fuente
RandomState
implementaciones más nuevas en desarrollo que use un algoritmo que tenga flujos configurables. Es decir, inicializa cadaRandomState
instancia con la misma semilla y diferentes ID de flujo (simplemente incrementado está bien), y tiene garantizado flujos independientes. pypi.python.org/pypi/randomstateUna solución que se usa en el procesamiento paralelo es usar su generador aleatorio , donde es su semilla, por lotes:Φ(u) u N
donde . De esta manera, usa una sola semilla y sus secuencias son todas uniformes e independientes.Φn(u)=Φ(Φn−1(u))
fuente
Ahora hay un paquete de Python llamado RandomGen que tiene métodos para lograr esto.
Es compatible con corrientes independientes creadas a partir de una sola semilla, así como un protocolo de salto de más edad generadores de números aleatorios, como MT19937.
fuente
Algunas personas afirman que hay correlaciones en los números aleatorios generados por semillas secuenciales. /programming/10900852/near-seeds-in-random-number-generation-may-give-similar-random-numbers No estoy seguro de cuán cierto es eso.
Si le preocupa, ¿por qué no usar un único generador de números aleatorios para elegir las semillas de todos los otros generadores?
fuente