suma repetir rango para numeros generar funcion decimales arreglo aleatorios c++ c++11

repetir - Generación aleatoria de números en C++ 11, cómo generar, ¿cómo funcionan?



generar numeros aleatorios en un arreglo en c++ (2)

Recientemente me encontré con una nueva forma de generar números aleatorios en C ++ 11 pero no pude digerir los papers que leí al respecto (qué es ese motor, término matemático como distribución, "donde todos los enteros producidos son igualmente probables ").

Entonces, ¿alguien puede explicar qué son, qué significan, cómo generar, cómo funcionan? etc. (puede llamarlo todo en una pregunta frecuente sobre la generación de números aleatorios).


La pregunta es demasiado amplia para una respuesta completa, pero déjame elegir algunos puntos interesantes:

Por qué "igualmente probable"

Supongamos que tiene un generador de números aleatorios simple que genera los números 0, 1, ..., 10, cada uno con la misma probabilidad (piense en esto como el rand() clásico rand() ). Ahora quiere un número aleatorio en el rango 0, 1, 2, cada uno con la misma probabilidad. Su reacción instintiva sería tomar rand() % 3 . Pero espere, los restantes 0 y 1 ocurren más a menudo que los restantes 2, ¡así que esto no es correcto!

Es por eso que necesitamos distribuciones adecuadas, que toman una fuente de enteros aleatorios uniformes y los convierten en nuestra distribución deseada, como Uniform[0,2] en el ejemplo. ¡Lo mejor es dejar esto en una buena biblioteca!

Motores

Así, en el corazón de todo lo aleatorio hay un buen generador de números pseudoaleatorios que genera una secuencia de números que se distribuyen uniformemente durante un cierto intervalo, y que idealmente tienen un período muy largo. La implementación estándar de rand() no suele ser la mejor, por lo que es bueno tener una opción. Linear-congruente y el twister de Mersenne son dos buenas elecciones (en realidad, LG también es usado por rand() ); nuevamente, es bueno dejar que la biblioteca maneje eso.

Cómo funciona

Fácil: primero, configure un motor y séllelo. La semilla determina completamente la secuencia completa de números "aleatorios", por lo que a) utilice una diferente (por ejemplo, tomada de /dev/urandom ) cada vez, y b) almacene la semilla si desea recrear una secuencia de elecciones aleatorias.

#include <random> typedef std::mt19937 MyRNG; // the Mersenne Twister with a popular choice of parameters uint32_t seed_val; // populate somehow MyRNG rng; // e.g. keep one global instance (per thread) void initialize() { rng.seed(seed_val); }

Ahora podemos crear distribuciones:

std::uniform_int_distribution<uint32_t> uint_dist; // by default range [0, MAX] std::uniform_int_distribution<uint32_t> uint_dist10(0,10); // range [0,10] std::normal_distribution<double> normal_dist(mean, stddeviation); // N(mean, stddeviation)

... ¡Y usa el motor para crear números aleatorios!

while (true) { std::cout << uint_dist(rng) << " " << uint_dist10(rng) << " " << normal_dist(rng) << std::endl; }

Concurrencia

Una razón más importante para preferir <random> al rand() tradicional rand() es que ahora es muy claro y obvio cómo hacer que la generación de números aleatorios sea segura: O bien proporcione a cada hilo su propio motor local de subprocesos, sembrado en un hilo. semilla local, o sincronizar el acceso al objeto del motor.

Misc

  • Un interesante artículo sobre TR1 al azar en codeguru.
  • Wikipedia tiene un buen resumen (gracias, @Justin).
  • En principio, cada motor debe typedef un result_type , que es el tipo integral correcto para usar para la semilla. Creo que tuve una implementación buggy una vez que me obligó a forzar la semilla para std::mt19937 a uint32_t en x64, finalmente esto debería ser reparado y puedes decir MyRNG::result_type seed_val y así hacer que el motor sea fácilmente reemplazable.

Un generador de números aleatorios es una ecuación que, dado un número, le dará un nuevo número. Normalmente, usted proporciona el primer número o se extrae de algo así como la hora del sistema.

Cada vez que solicite un nuevo número, usará el número anterior para ejecutar la ecuación.

Un generador de números aleatorios no se considera muy bueno si tiende a producir el mismo número con mayor frecuencia que otros números. es decir, si quería un número aleatorio entre uno y cinco y tenía esta distribución de números:

  • 1: 1%
  • 2: 80%
  • 3: 5%
  • 4: 5%
  • 5: 9%

2 se genera mucho más a menudo que cualquier otro número, por lo que es más probable que se produzca que otros números. Si todos los números fueran iguales, tendrías un 20% de probabilidad de obtener cada número cada vez. Para decirlo de otra manera, la distribución anterior es muy desigual porque se favorece a 2. Una distribución con todos los 20% sería par.

Por lo general, si desea un número aleatorio verdadero, extraería datos de un clima u otra fuente natural en lugar de un generador de números aleatorios.