2012-06-12 38 views
13

我試圖使用C++ 11的方法來隨機數生成:如何重置隨機數引擎?

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

的輸出是:

0.13453 
-0.146382 

0.46065 
-1.87138 

0.163712 
-0.214253 

這意味着,在第一和第三序列是不即使相同他們播種的數量相同。請問我做錯了什麼?

std::normal_distribution<double> 

只是一個數學意義上的函數(確定性地產生y)或我是否錯過了某些東西?如果它只是一個函數,重置方法實際上做了什麼?

回答

19

您正在綁定引擎和分配,以下調用重置不會影響綁定函數。

的解決方案是結合引擎和發行

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

就是這樣。我想我必須學習更多的STL :)它完美地適用於您的解決方案。謝謝! –

+0

'自動生成器= std :: bind(正常,std :: ref(引擎));'我猜是足夠了。 – Tengis

11

您所遇到的問題是std::bind引用。 std::bind製作其參數的副本。原因std::bind進行復制是因爲函數將在參數可能不再存在時在將來某個未知點處調用。這意味着您撥打engine.seed()等無用。使用std::ref你可以通過引用來綁定你的參數,這會給你預期的輸出。

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

謝謝!就是這樣。現在它工作正常! :) –