Normalmente cuando siembro un generador secuencial de números aleatorios en C, uso la llamada
srand(time(NULL))
luego usa
rand() mod N
para obtener un entero aleatorio entre 0 y N-1. Sin embargo, cuando hago esto en paralelo, las llamadas al tiempo (NULL) están tan cerca una de la otra que terminan siendo exactamente el mismo número.
He intentado usar un generador lineal de números aleatorios congruenciales:
para algunos enteros y .
Sé que elegir para algún entero grande produce resultados rápidos porque el operador del módulo se puede calcular truncando dígitos. Sin embargo, me resulta difícil establecer semillas que produzcan secuencias aleatorias con un gran período en paralelo. Sé que la duración de un período es máxima si
- c y m son números primos entre sí
- a-1 es divisible por todos los factores primos de m
- si m es un múltiplo de 4, a-1 también debe ser un múltiplo de 4.
(fuente: wikipedia )
Pero, ¿cómo me aseguro de que todas las secuencias de números aleatorios tengan esta propiedad máxima? En términos de MPI, ¿cómo incorporo rank
y size
para producir períodos máximos utilizando el método lineal congruencial? ¿Sería más fácil usar un Fibonacci rezagado o un Mersenne Twister para producir flujos aleatorios paralelos más largos?
mod
para tomar los bits de bajo orden, como sugirió Jonathan Dursi , son mucho menos aleatorios. En su lugar, divida su número aleatorio (int) por maxint / range para obtener el rango que necesita. Le cuesta una división, pero probablemente sea una opción más barata para mejorar la calidad de su secuencia de números aleatorios que cambiar a otro PRNG.