2012-06-12 25 views
13

Próbuję użyć podejście do generowania liczb losowych C++ 11:Jak zresetować silnik liczb losowych?

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

wyjście jest:

0.13453 
-0.146382 

0.46065 
-1.87138 

0.163712 
-0.214253 

Oznacza to, że pierwsza i trzecia sekwencja nie są identyczne, nawet jeśli są zaszczepione tą samą liczbą. Proszę, co ja robię źle? Czy jest to tylko funkcja w sensie matematycznym (generuje y z x deterministycznie) lub czy brakuje mi czegoś? Jeśli jest to tylko funkcja, co właściwie robi metoda resetowania?

Odpowiedz

19

Podłączasz silnik i dystrybucję, takie połączenia po zresetowaniu nie wpłyną na powiązaną funkcję.

Rozwiązaniem jest związać odniesień do silnika i dystrybucji

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

To było to. Wydaje mi się, że muszę dużo nauczyć się STL :) Działa idealnie z twoim rozwiązaniem. Dzięki! –

+0

'auto generator = std :: bind (normalny, std :: ref (silnik));' wystarczy, jak sądzę. – Tengis

11

Problem masz jest z std::bind. std::bind tworzy kopie swoich argumentów. Powód std::bind tworzy kopie, ponieważ funkcja będzie wywoływana w pewnym nieznanym momencie w przyszłości, gdy argumenty przestaną istnieć. Oznacza to, że Twoje połączenia z numerami engine.seed() itp. Są bezużyteczne. Używając std::ref możesz powiązać swoje argumenty przez odniesienie, które dadzą oczekiwane wyniki.

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

Dziękujemy! To było to. Teraz działa dobrze! :) –

Powiązane problemy