2011-01-24 103 views
8

我想通過使用不同的種子數重置隨機序列。當運行這個測試代碼:設置種子提升::隨機

boost::mt19937 gener(1); 
boost::normal_distribution<> normal(0,1); 
boost::variate_generator<boost::mt19937&,boost::normal_distribution<> > rng(gener, normal); 
cout << rng() << endl; 
cout << rng() << endl; 
cout << rng() << endl; 
gener.seed(2); 
cout << rng() << endl; 
cout << rng() << endl; 
gener.seed(1); 
cout << rng() << endl; 
gener.seed(2); 
cout << rng() << endl; 
gener.seed(3); 
cout << rng() << endl; 

我得到以下輸出:

# seed(1) via constructor 
-2.971829031 
1.706951063 
-0.430498971 
# seed(2) 
-2.282022417 
-0.5887503675 
# seed(1) 
0.2504171986 
# seed(2) 
-0.5887503675 
# seed(3) 
0.2504171986 

很顯然,我做的事情非常錯誤的。我怎樣才能克服這個問題?

回答

14

繼吉姆,艾倫和伊戈爾的建議做了一些修改代碼:rng.engine().seed()代替gener.seed(),並調用後調用rng.distribution().reset()rng.engine().seed(),它像一個魅力。

非常感謝!

1

我相信boost::variate_generator<>複製了您的boost::mt19937 gener對象。 因此,當您爲gener複製副本時,它對rng對象的構成已經構成 沒有影響。每次重新安裝新對象時,都應該給予您想要的行爲(免責聲明:未經測試!)

+0

我相信,補種正在對RNG一定的影響,因爲我得到的重複值-0.5887503675和0.2504171986。但不幸的是,根本不是我所期望的。 – 2011-01-24 14:00:29

+0

很高興看到問題解決,但我可以問爲什麼boost :: variate_generator <>`在這種情況下生成`gener`的副本?我認爲OP在編寫`boost :: variate_generator >時傳遞了引用,我是否缺少任何東西?... – Vokram 2012-08-17 06:49:28

5

您應該在調用gener.seed()之後調用normal.reset()。這是爲了確保正常輸出不會依賴於以前的任何輸出。

(分佈可能是緩存,你需要清除一些狀態。)

+0

是的,它看起來像是一個緩存問題。我按照你的建議做了,但我仍然得到相同的結果... – 2011-01-24 20:03:21

1

很高興看到問題解決!但我想我只是想通了,爲什麼艾倫的方法是行不通的......

當寫boost::variate_generator<boost::mt19937&,boost::normal_distribution<> > rng(gener, normal),你沒有創建的gener另一個副本,因爲它是通過引用調用,但你創建的另一個副本normalvariate_generate

因此,而不是normal.reset,它只能重置原始normal,您應該使用rng.distribution().reset()。但你可以保留gener.seed(),我懷疑它會和rng.engine().seed()有相同的效果。

我在我的代碼中測試過它,它按預期工作。

好,以防萬一有人會關心:)