2012-06-12 18 views
13

estoy tratando de utilizar el enfoque de C++ 11 de generación de números aleatorios:¿Cómo restablecer un motor de número aleatorio?

#include <random> 
#include <functional> 
#include <iostream> 

int main(int argc, char *argv[]) 
{  
    std::normal_distribution<double> normal(0, 1); 
    std::mt19937 engine; // Mersenne twister MT19937 
    auto generator = std::bind(normal, engine); 

    int size = 2; 

    engine.seed(0); 
    normal.reset(); 
    for (int i = 0; i < size; ++i) 
     std::cout << generator() << std::endl; 

    std::cout << std::endl; 

    engine.seed(1); 
    normal.reset(); 
    for (int i = 0; i < size; ++i) 
     std::cout << generator() << std::endl; 

    std::cout << std::endl; 

    engine.seed(0); 
    normal.reset(); 
    for (int i = 0; i < size; ++i) 
     std::cout << generator() << std::endl; 

    return 0; 
} 

La salida es:

0.13453 
-0.146382 

0.46065 
-1.87138 

0.163712 
-0.214253 

Eso significa que la primera y la tercera secuencia no son idénticos, incluso si ellos son sembrados con el mismo número. Por favor, ¿qué estoy haciendo mal? Es la

std::normal_distribution<double> 

sólo una función en el sentido matemático (produce y de forma determinista x) o me estoy perdiendo algo? Si solo es una función, ¿qué hace realmente el método de reinicio?

Respuesta

19

Está vinculando el motor y la distribución, por lo que las siguientes llamadas al reiniciar no afectarán a la función enlazada.

La solución es unir referencias al motor y la distribución

auto generator = std::bind(std::ref(normal), std::ref(engine)); 
+0

Eso fue todo. Creo que tengo que aprender mucho más el STL :) Funciona perfectamente con tu solución. ¡Gracias! –

+0

'auto generator = std :: bind (normal, std :: ref (motor)); es suficiente, supongo. – Tengis

11

El problema que tiene es con std::bind. std::bind hace copias de sus argumentos. El motivo por el cual std::bind realiza copias se debe a que se llamará a la función en algún punto desconocido en el futuro cuando los argumentos ya no existan. Esto significa que sus llamadas al engine.seed(), etc. son inútiles. Utilizando std::ref puede vincular sus argumentos por referencia lo que le dará el resultado esperado.

auto generator = std::bind(std::ref(normal), std::ref(engine)); 
+0

¡Gracias! Eso fue todo. ¡Ahora funciona bien! :) –

Cuestiones relacionadas