He visto bastantes recomendaciones para no sembrar generadores de números pseudoaleatorios más de una vez por ejecución, pero nunca acompañados de una explicación exhaustiva. Por supuesto, es fácil ver por qué la (C/C++) siguiente ejemplo no es una buena idea:Problemas con el siembra de un generador de números pseudoaleatorios más de una vez?
int get_rand() {
srand(time(NULL));
return rand();
}
ya llamar get_rand
varias veces por segundo produce resultados repetidos.
¿Pero no sería el siguiente ejemplo una solución aceptable?
MyRand.h
#ifndef MY_RAND_H
#define MY_RAND_H
class MyRand
{
public:
MyRand();
int get_rand() const;
private:
static unsigned int seed_base;
};
#endif
MyRand.cpp
#include <ctime>
#include <cstdlib>
#include "MyRand.h"
unsigned int MyRand::seed_base = static_cast<unsigned int>(time(NULL));
MyRand::MyRand()
{
srand(seed_base++);
}
int MyRand::get_rand() const
{
return rand();
}
main.cpp
#include <iostream>
#include "MyRand.h"
int main(int argc, char *argv[])
{
for (int i = 0; i < 100; i++)
{
MyRand r;
std::cout << r.get_rand() << " ";
}
}
es decir, aunque el constructor MyRand
se llama varias veces en sucesión rápida, cada llamada a srand
tiene un parámetro diferente. Obviamente, esto no es seguro para subprocesos, pero tampoco lo es rand
.
Podría agregar que el propósito de este ejercicio es aliviar la "carga" de llamar a srand del cliente de 'MyRand', donde' MyRand' podría estar modelando un dado. Pero, por otro lado, si también construimos ruedas de fortuna, lanzamientos de monedas, etc. de la misma manera, obtendremos muchas semillas. – a038c56f