2012-05-22 9 views

Respuesta

15

Boost proporciona muchas herramientas para la generación de números aleatorios. Para distribuciones uniformes que tienen éste:

http://www.boost.org/doc/libs/1_49_0/doc/html/boost/random/uniform_real_distribution.html

EDIT: actualizado para incluir la nueva aplicación de C++ 11. Para el caso de los números enteros, aquí se tiene la referencia:

http://en.cppreference.com/w/cpp/numeric/random/uniform_int_distribution

Un ejemplo sencillo sería:

#include <random> 
#include <iostream> 
int main() 
{ 
    std::random_device rd; 
    std::mt19937 gen(rd()); 
    std::uniform_int_distribution<> dis(1, 6); 
    for(int n=0; n<10; ++n) 
     std::cout << dis(gen) << ' '; 
    std::cout << '\n'; 
} 
+5

y ahora son parte de ** C++ 11 ** por lo que son estándar. –

+0

@ K-ballo eso es genial! C++ 11 está haciendo C++ mucho más fácil :) – betabandido

+1

Tal vez un pequeño ejemplo de código podría ser útil. – authchir

10

para generar números pseudo-aleatorios en C++, una muy buena opción es el uso de la Mersenne twister generador de números pseudoaleatorios motor: std::mt19937 del <random> encabezado.

Podemos pensar en este motor como recuadro negro que escupe de alta calidad bits aleatorios.

Luego, estos bits aleatorios pueden ser conformado de alguna salida enteros utilizando una distribución ; en particular, para obtener distribuidos uniformemente números pseudoaleatorios, se puede usar std::uniform_int_distribution.

Tenga en cuenta que el objeto del motor se debe inicializar con una semilla .
std::random_device se puede utilizar para ese fin.

Por lo tanto, este proceso se puede resumir en tres pasos lógicos:

  1. crear una instancia de std::random_device, para obtener una semilla no determinista para el motor de Mersenne Twister.
  2. Crea una instancia de std::mt19937motor, para obtener bits pseudoaleatorios de alta calidad.
  3. Utilice std::uniform_int_distribution a forma estos bits aleatorios en enteros uniformemente distribuidos.
  4. código

compilable C++ sigue:

#include <iostream>  // for console output 
#include <random>  // for pseudo-random number generators and distributions 

int main() 
{ 
    // Use random_device to generate a seed for Mersenne twister engine. 
    std::random_device rd;  

    // Use Mersenne twister engine to generate pseudo-random numbers. 
    std::mt19937 engine(rd()); 

    // "Filter" MT engine's output to generate pseudo-random integer values, 
    // **uniformly distributed** on the closed interval [0, 99]. 
    // (Note that the range is [inclusive, inclusive].) 
    std::uniform_int_distribution<int> dist(0, 99); 

    // Generate and print 10 pseudo-random integers 
    for (int i = 0; i < 10; ++i) 
    { 
     std::cout << dist(engine) << ' '; 
    } 
    std::cout << std::endl; 
} 

Para más detalles sobre la generación de números pseudo-aleatorios en C++ (incluyendo razones por rand() es no bueno), consulte este vídeo de Stephan T. Lavavej (de Going Native 2013):

rand() Considered Harmful

+0

+1 Seguro que demoró un poco, pero finalmente se fusionó. Es posible que desee editar su pregunta para indicar que también formó parte de una combinación y un comentario al OP para que comprendan por qué esta nueva respuesta apareció con una fecha anterior. –

+0

No sé por qué todos dicen que Mersenne Twister es tan genial y de "alta calidad". No es. Es complicado, tiene una enorme huella de memoria y aún falla en múltiples pruebas del conjunto de pruebas TestU01 BigCrush. Actualmente hay varios PRNG más simples, más rápidos y de mayor calidad con periodos adecuados. – plasmacel

+0

@plasmacel: Le pregunté a Stephan T. Lavavej (mantenedor de VC STL) y me confirmó que es el mejor PRNG estándar. ¿Qué propones como mejores alternativas? –

0

para generar una o número especificado de variables aleatorias con distribución uniforme en el dominio entero usando std::generate_n y boost:

#include <iostream> 
#include <algorithm> 
#include <boost/random.hpp> 

/* 
* 
*/ 
int main(int argc, char** argv) { 
    boost::mt19937 rand_generator(std::time(NULL)); 
    boost::random::uniform_int_distribution<> int_distribution(0, 100); 

    //Need to pass generator 
    std::cout << int_distribution(rand_generator) << std::endl; 

    //Associate generator with distribution 
    boost::random::variate_generator<boost::mt19937&, 
      boost::random::uniform_int_distribution<> 
      > int_variate_generator(rand_generator, int_distribution); 

    //No longer need to pass generator 
    std::cout << int_variate_generator() << std::endl; 
    std::generate_n(std::ostream_iterator<int>(std::cout, ","), 3, int_variate_generator); 
    return 0; 
} 
Cuestiones relacionadas