Generar números aleatorios con la biblioteca aleatoria C++11

Como sugiere el título, estoy intentando encontrar una forma de generar números aleatorios utilizando la nueva librería <random> de C++11. Lo he intentado con este código:

std::default_random_engine generator;
std::uniform_real_distribution<double> uniform_distance(1, 10.001);

El problema con el código que tengo es que cada vez que lo compilo y lo ejecuto, siempre genera los mismos números. Así que mi pregunta es ¿qué otras funciones en la biblioteca aleatoria puede lograr esto mientras que ser verdaderamente al azar?

Para mi caso particular, estaba tratando de obtener un valor dentro del rango [1, 10].

Solución

Stephan T. Lavavej (stl) de Microsoft dio una charla en Going Native sobre cómo usar las nuevas funciones aleatorias de C++11 y por qué no usar rand(). En ella, incluyó una diapositiva que básicamente resuelve tu pregunta. He copiado el código de esa diapositiva a continuación.

Puedes ver su charla completa aquí: http://channel9.msdn.com/Events/GoingNative/2013/rand-Considered-Harmful


#include 
#include 

int main() {
    std::random_device rd;
    std::mt19937 mt(rd());
    std::uniform_real_distribution dist(1.0, 10.0);

    for (int i=0; i
Comentarios (9)

Aquí'hay algo que acabo de escribir en ese sentido::

#include 
#include 
#include 

using namespace std;

//==============================================================
// RANDOM BACKOFF TIME
//==============================================================
class backoff_time_t {
  public:
    random_device                      rd;
    mt19937                            mt;
    uniform_real_distribution  dist;

    backoff_time_t() : rd{}, mt{rd()}, dist{0.5, 1.5} {}

    double rand() {
      return dist(mt);
    }
};

thread_local backoff_time_t backoff_time;

int main(int argc, char** argv) {
   double x1 = backoff_time.rand();
   double x2 = backoff_time.rand();
   double x3 = backoff_time.rand();
   double x4 = backoff_time.rand();
   return 0;
}

~

Comentarios (0)

Hay dos situaciones habituales. La primera es que quieras números aleatorios y no te importe demasiado la calidad o la velocidad de ejecución. En ese caso, utilice la siguiente macro

#define uniform() (rand()/(RAND_MAX + 1.0))

que te da p en el rango de 0 a 1 - epsilon (a menos que RAND_MAX sea mayor que la precisión de un double, pero preocúpate de eso cuando llegues a ello).

int x = (int) (uniforme() * N);

Ahora da un entero aleatorio en 0 a N -1.

Si necesitas otras distribuciones, tienes que transformar p. O a veces es más fácil llamar a uniform() varias veces.

Si quieres un comportamiento repetible, siembra con una constante, de lo contrario siembra con una llamada a time().

Ahora bien, si le preocupa la calidad o el rendimiento en tiempo de ejecución, reescriba uniform(). Pero de lo contrario no toque el código. Mantenga siempre uniform() en 0 a 1 menos epsilon. Ahora puede envolver la librería de números aleatorios de C++ para crear una uniform() mejor, pero esa es una opción de nivel medio. Si te molestan las características del RNG, entonces'también vale la pena invertir un poco de tiempo para entender cómo funcionan los métodos subyacentes, y luego proporcionar uno. Así tendrá un control total del código, y podrá garantizar que con la misma semilla, la secuencia será siempre exactamente la misma, independientemente de la plataforma o de la versión de C++ a la que esté enlazando.

Comentarios (2)