2009-03-16 16 views
5

Deseo suministrar un número y luego recibir un conjunto de números aleatorios. Sin embargo, quiero que esos números sean los mismos, independientemente de la computadora con la que lo ejecute (suponiendo que suministre la misma semilla).Flujos de números aleatorios deterministas en C++ STL

Básicamente mi pregunta es: en C++, si hago uso de rand(), pero el suministro srand() con una semilla definida por el usuario en lugar de la hora actual, voy a ser capaz de generar la misma secuencia de números aleatorios en cualquier ordenador?

Respuesta

5

srand() & rand() no son parte de la STL. En realidad, son parte del tiempo de ejecución de C. Sí, producirán los mismos resultados siempre que sea la misma implementación de srand()/rand().

Dependiendo de sus necesidades, es posible que desee considerar el uso de Boost.Random. Proporciona varios generadores de números aleatorios de alta calidad.

+0

Voy a tener que decir +1 en Boost.Random. Funciona muy bien e incluso tienen clases deterministas específicas. – rlbond

4

Suponiendo que las implementaciones de rand() son las mismas, sí.

La manera más fácil de garantizar esto es incluir una implementación conocida de rand() con su programa, ya sea incluida en el código fuente de su proyecto o en forma de una biblioteca que puede administrar.

+0

"Cada" es una palabra GRANDE. Calificar esto con "Most" en lugar de "Every" es necesario. La mayoría de los RNG modernos están diseñados para funcionar de manera consistente en la mayoría de las familias de hardware de 32 bits. Pero eso no dice nada acerca de las máquinas de 64 bits o el raro hardware peculiar. –

+0

Es por eso que dije que necesitabas tener una copia de rand() que puedes controlar o, al menos, predecir. – greyfade

+0

Lo suficiente :-) La única otra cosa de qué asegurarse es que es portátil en términos de tipos de datos para todas sus arquitecturas de destino. –

0

Creo que si suministras srand con la misma semilla, obtendrás los mismos resultados. Esa es prácticamente la definición de una semilla en términos de generadores de números pseudoaleatorios.

7

Hay docenas de PRNG s disponibles como bibliotecas. Elegir uno. Tiendo a usar Mersenne Twister.

Al utilizar una biblioteca suministrada externamente, elude el riesgo de una implementación extraña o con errores de la biblioteca de su idioma rand(). Siempre que sus plataformas se ajusten a la misma semántica matemática, obtendrá resultados consistentes.

MT es uno de mis favoritos porque soy físico, y utilizo estas cosas para Monte Carlo, donde la garantía de igualdad de distribución a las altas dimensiones es importante. ¡Pero no usa MT como un PRNG criptográfico!

+0

Por curiosidad, ¿por qué no usar MT para crypto? ¿Te importa compartir un enlace? (Es una pregunta honesta, no estoy tratando de ser sarcástica :-) –

+0

Se predice fácilmente a partir de un pequeño número de salidas conocidas. Hay un enlace en el artículo de wikipedia. – dmckee

+1

http://en.wikipedia.org/wiki/Mersenne_twister#Application –

0

Sí. Para una semilla determinada (valor inicial), la secuencia de números que devuelve rand() siempre será la misma.

+0

Debe calificar esto con "una implementación determinada de rand()". No hay dos PRNG garantizados para producir la misma secuencia. – greyfade

1

No, la ANSI C estándar solamente especifica que rand() debe producir una corriente de números enteros aleatorios entre 0 y RAND_MAX, que debe ser de al menos 32.767 (source). Esta secuencia debe ser determinista solo en que, para una implementación dada en una máquina dada, debe producir la misma secuencia entera dada la misma semilla.

Quiere un PRNG portátil.Mersenne Twister (muchas implementaciones vinculadas en la parte inferior) es bastante portable, como es Ben Pfaff's homegrown C99-compliant PRNG. Boost.Random debería estar bien también; Mientras escribe su código en C++, usar Boost no limita mucho su elección de plataformas (aunque algunos compiladores "menores" (es decir, no compatibles) pueden tener problemas con el uso intensivo de la metaprogramación de plantillas). Esto solo es realmente un problema para las plataformas integradas de bajo volumen y quizás arquitecturas de investigación novedosas, por lo que si "cualquier computadora" se refiere a "cualquier plataforma x86/PPC/ARM/SPARC/Alpha/etc. que GCC tenga como objetivo", cualquiera de las arriba debería hacer bien.