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

Como sugiere el título, estoy tratando de encontrar una forma de generar números aleatorios usando la nueva biblioteca C ++ 11 . Lo he intentado con este código:

 std::default_random_engine generator; std::uniform_real_distribution 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. Entonces mi pregunta es ¿qué otras funciones en la biblioteca al azar pueden lograr esto siendo verdaderamente al azar?

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

Stephan T. Lavavej (stl) de Microsoft hizo una charla en Going Native sobre cómo usar las nuevas funciones aleatorias de C ++ 11 y por qué no usar rand() . En él, incluyó una diapositiva que básicamente resuelve tu pregunta. Copié el código de la 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<16; ++i) std::cout << dist(mt) << "\n"; } 

Utilizamos random_device una vez para sembrar el generador de números aleatorios llamado mt . random_device() es más lento que mt19937 , pero no necesita ser sembrado porque solicita datos aleatorios de su sistema operativo (que se originará en varias ubicaciones, como RdRand, por ejemplo).


Al uniform_real_distribution esta pregunta / respuesta , parece que uniform_real_distribution devuelve un número en el rango [a, b) , donde desea [a, b] . Para hacer eso, nuestra uniform_real_distibution debería verse así:

 std::uniform_real_distribution dist(1, std::nextafter(10, DBL_MAX)); 

Mi biblioteca ‘aleatoria’ proporciona un envoltorio muy conveniente para las clases aleatorias de C ++ 11. Puedes hacer casi todas las cosas con un simple método ‘get’.

Ejemplos:

  1. Número aleatorio en un rango

     auto val = Random::get(-10, 10); // Integer auto val = Random::get(10.f, -10.f); // Float point 
  2. Random booleano

     auto val = Random::get( ) // 50% to generate true auto val = Random::get( 0.7 ) // 70% to generate true 
  3. Valor aleatorio de un std :: initilizer_list

     auto val = Random::get( { 1, 3, 5, 7, 9 } ); // val = 1 or 3 or... 
  4. Iterador aleatorio del rango del iterador o de todos los contenedores

     auto it = Random::get( vec.begin(), vec.end() ); // it = random iterator auto it = Random::get( vec ); // return random iterator 

¡Y aún más cosas! Mira la página de github:

https://github.com/effolkronium/random

Aquí hay algo que acabo de escribir a lo largo de esas líneas ::

 #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; } 

~

Tienes dos situaciones comunes. La primera es que quiere números aleatorios y no se preocupa demasiado por la calidad o la velocidad de ejecución. En ese caso, use la siguiente macro

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

eso le da p en el rango de 0 a 1 – epsilon (a menos que RAND_MAX sea mayor que la precisión de un doble, pero preocúpese por eso cuando llegue).

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

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

Si necesita otras distribuciones, debe transformar p. O a veces es más fácil llamar al uniforme () varias veces.

Si desea un comportamiento repetible, siembre con una constante, de lo contrario siembre con una llamada a la hora ().

Ahora, si le molesta la calidad o el rendimiento del tiempo de ejecución, vuelva a escribir el uniforme (). Pero de lo contrario, no toques el código. Mantenga siempre uniforme () en 0 a 1 menos épsilon. Ahora puede envolver la biblioteca de números aleatorios de C ++ para crear un uniforme mejor (), pero esa es una especie de opción de nivel medio. Si le molestan las características del RNG, también vale la pena invertir un poco de tiempo para comprender cómo funcionan los métodos subyacentes, y luego proporcionar uno. Así que tienes el control completo del código, y puedes garantizar que con la misma similitud, la secuencia siempre será exactamente la misma, independientemente de la plataforma o de la versión de C ++ a la que estés enlazando.

    Intereting Posts