2010-08-17 10 views
5

Me gusta mucho poder generar el mismo conjunto de datos pseudoaleatorios repetidamente, especialmente con el ajuste del código experimental. A través de la observación, diría que rand() parece dar la misma secuencia de números cada vez *.¿El rand de stdlib() siempre da la misma secuencia?

¿Está garantizado para hacer esto para ejecuciones repetidas en la misma máquina/para diferentes máquinas/para diferentes arquitecturas?

* Para la misma semilla obviamente.

Respuesta

18

Sí, dado el mismo entorno para el programa. A partir de la norma C § 7.20.2.2/2,

La función srand utiliza el argumento como una semilla para una nueva secuencia de números pseudo-aleatorios que ser devueltos por las posteriores llamadas a rand. Si se llama a srand con el mismo valor inicial, se repetirá la secuencia de números pseudoaleatorios. Sirand se llama antes se han hecho todas las llamadas a srand, la misma secuencia se genera como cuando srand se llama en primer lugar con un valor de semilla 1.

Por supuesto, esto supone que está utilizando la misma aplicación detalle (es decir, la misma máquina, la misma biblioteca en el mismo período de ejecución). El estándar C no exige un algoritmo estándar de generación de números aleatorios, por lo tanto, si ejecuta el programa con una biblioteca estándar distinta de C, se puede obtener una secuencia de números aleatorios diferente.

Consulte la pregunta Consistent pseudo-random numbers across platforms si necesita una secuencia de números aleatorios portátil y garantizada con una semilla determinada.

+0

estándar WIN ... –

+0

OK. Estoy de acuerdo en que para una lib de tiempo de ejecución particular, la secuencia será la misma. Entonces, una vez que se genera una aplicación (contra una versión de tiempo de ejecución específica), siempre generará la misma secuencia. Pero esto depende de la versión diferente del tiempo de ejecución (es decir, a través de OS/arquitectura/versiones de tiempo de ejecución) etc. Si eso implica que el estándar define una implementación exacta para el algoritmo rand() (de lo contrario, ¿cómo se aseguraría dos sistemas operativos independientes? se conforman). –

+3

No se extiende a las diferentes versiones de los tiempos de ejecución, y si enlaza dinámicamente con la implementación de 'rand()' podría potencialmente actuar de manera diferente sin reconstruir nada. –

1

No.

El estándar C dice:

Si srand se llama a continuación, con el mismo valor semilla, la secuencia de números pseudo-aleatorios se repiten.

Pero en ningún caso dice cuál es realmente la secuencia de números pseudoaleatorios, por lo que difiere en las implementaciones.

La única garantía hecho es que rand() dará la misma secuencia de números para una semilla dada para una implementación dada. No hay garantía de que la secuencia sea la misma en diferentes máquinas o arquitecturas diferentes, y es casi seguro que no lo será.

0

Si necesita usar exactamente el mismo conjunto de números pseudoaleatorios para fines experimentales, una cosa que podría hacer es usar srand para generar una secuencia larga de números aleatorios y escribirlos en un archivo/base de datos. Luego, escriba una función portátil de "generador de números aleatorios" que devuelva los valores secuencialmente desde ese archivo. De esta forma, puede estar seguro de que está utilizando los mismos datos de entrada independientemente de la plataforma, la implementación srand o el valor inicial.

+0

Buena idea. Si tuviera un requerimiento para hacer eso, ciertamente tomaría ese enfoque. Mi pregunta surgió más por curiosidad que por la necesidad de una secuencia conocida. – Joe

+0

¿O simplemente podría escribir una función aleatoria propia? – dcousens

0

Al cambiar a una máquina/tiempo de ejecución diferente/lo que sea, puede que no tenga suerte. Hay otra opción posible, la familia de funciones drand48. Estos están normalizados para usar el mismo algoritmo en todas las máquinas.

2

Se garantiza que proporciona la misma secuencia para la misma semilla pasada a srand() - pero solo durante la ejecución única del programa. En general, si una implementación tiene una opción de comportamiento, no existe un requisito específico para que esa opción permanezca igual en las ejecuciones posteriores.

Sería conforme para una implementación elegir una "semilla maestra" al inicio de cada programa, y ​​usar eso para perturbar el generador de números pseudoaleatorio de una manera que es diferente cada vez que se inicia el programa.

Si desea obtener más determinismo, debe implementar un PRNG con parámetros específicos en su programa.

0

Si se encuentra en un entorno UNIX/Linux Enviroment se puede ver el drand48() y srand48 () en sus páginas de manual si no está puede ver online manuals para el lenguaje C. Los prototipos se pueden encontrar en /usr/include/stdlib.h. El primero usa el Método congruente lineal que se usa con frecuencia en simulaciones.

Si proporciona la misma semilla para srand48(), es decir, srand48 (2) y luego coloca el dran48() en un bucle for, la secuencia será la misma siempre. decir

include stdio.h 
include stdlib.h 
double drand48(); 
int main(void){ 
    int i; 
    double rn; 
    srand48(2); 
    for(i=0; i<10; i++){ 
     randNum = drand48(); 
     printf("%.6l\n", randNum); 
     return 0; 
} 
Cuestiones relacionadas