2015-01-20 173 views
0

我目前正試圖實現一個使用驗收拒絕方法的隨機數發生器(類)。因此我需要不同的C++ 11隨機數分佈(在我的情況下是正態分佈和均勻分佈)。我想盡可能使隨機數字,因此想要使用以下來建立功能:初始化列表中的種子序列初始化

[...] 
#include <random> 
#include <vector> 
[...] 
std::vector<int> seeds(16); 
std::mt19937 mt; 
std::minstd_rand seed_rng(101); // random seed 
for(size_t i=0;i<16;++i) seeds[i]=seed_rng(); 
std::seed_seq seq(seeds.begin(), seeds.end()); 
mt.seed(seq); 
rng_normal = std::bind(ndist, std::ref(mt)); 
[...] 

這很好地工作。但是,當我嘗試將所有這些現在放在構造函數中時,我無法再使用種子序列的初始化。我檢查了C++引用,但只是遇到了std :: seed_seq :: generate,這不是正確的解決方案。
有沒有辦法在填充矢量後在我的init列表中構造seed_seq? 有關seed_seq的參考,請參閱此處:
http://en.cppreference.com/w/cpp/numeric/random/seed_seq
謝謝您,提供任何建議!

+0

把這段代碼放在構造函數中有什麼問題?還是你問你可以在初始化列表中完成所有工作? – Praetorian 2015-01-20 18:42:55

+0

@Praetorian是的,對不起。我想在初始化列表中完成一切。 – 2015-01-20 18:50:00

回答

0

假設你不感興趣,保留用於構建mt19937seed_seq例如,你可以做這樣的事情:

struct foo 
{ 
    std::mt19937 mt; 
    std::normal_distribution<> ndist; 
    std::function<decltype(mt)::result_type()> rng_normal; 

    foo() 
    : mt{make_mersenne_twister()} 
    , rng_normal{std::bind(ndist, std::ref(mt))} 
    {} 

    static std::mt19937 make_mersenne_twister() 
    { 
     std::minstd_rand seed_rng(std::random_device{}()); // random seed 
     std::vector<int> seeds(16); 

     std::generate(seeds.begin(), seeds.end(), seed_rng); 

     std::seed_seq seq(seeds.begin(), seeds.end()); 
     return std::mt19937{seq}; 
    } 
}; 

std::random_device替換你的種子(101)。

保留seed_seq的問題在於它既不可複製也不可移動,因此將其構造委派給像我在梅森扭轉者那樣的功能是不可能的。

Live demo

+0

投票!謝謝,該解決方案實際上應該適合我!我想我會搜索,而seed_seq實際上不可移動也不可複製,因爲我猜這是有原因的...... – 2015-01-20 19:30:04

+0

@LeoW。由於你是新人,你的評論表明我的答案有幫助,所以我會向你提供有關[接受有用答案的作品]的常見問題解答(http://meta.stackexchange.com/questions/5234/how-does-accepting -an回答工作)。 – Praetorian 2015-01-27 06:06:36

0

我嚴重懷疑你的改進很值得。 std :: mt19937的單個值(和默認)構造函數在C++標準中指定。它相當於類似

static constexpr size_t WS = 32; 
static constexpr result_type IM = 1812433253; 
static constexpr result_type default_seed = 5489u; 

explicit mt19937(result_type value = default_seed) 
{ 
    state[0] = value; 
    for (int i = 1; i != state_size; ++i) 
    { 
     state[i] = i + IM * (state[i - 1]^(state[i - 1] >> (WS - 2))); 
    } 
} 

所以,它採用了XOR-SHIFT隨機數生成器,填補了狀態數組。鑑於參與此種子算法的人員以及工作人員將<random>納入標準,我認爲這是一個安全的選擇,假設他們知道std :: minstd_ran,但發現上述優勢用於播種梅森扭轉者。