2016-07-22 67 views
11

我有一個簡單的代碼示例:爲什麼GCC和MSVC std :: normal_distribution是不同的?

#include <iostream> 
#include <random> 
using namespace std; 
int main() { 
    minstd_rand0 gen(1); 
    uniform_real_distribution<double> dist(0.0, 1.0); 
    for(int i = 0; i < 10; ++i) { 
     cout << "1 " << dist(gen) << endl; 
    } 

    normal_distribution<double> dist2(0.0, 1.0); 
    minstd_rand0 gen2(1); 
    for(int i = 0; i < 10; ++i) { 
     cout << "2 " << dist2(gen2) << endl; 
    } 

    return 0; 
} 

我於gccmsvc編譯。我得到STD代碼diferent結果!( enter image description here

那麼,爲什麼GCC和MSVC std::normal_distribution結果diferent對於相同的種子和發電機,最重要的是,如何他們是一樣的嗎?

+13

迷人。我本來期望他們有100%不同的或100%相同的數字。他們是相同的,但重新排列的事實打擊了我的想法。 –

+2

而'uniform_real_distribution'結果與預期相同! – DuckQueen

+3

@MooingDuck:這裏的標準算法每次迭代產生兩個值。看起來他們都使用相同的算法實現,但兩者的哪一個返回並緩存的不同。 – Hurkyl

回答

6

這是有問題的,但標準遺憾的是沒有詳細指明隨機分佈的數字建設(很多)時使用何種算法,並有多種有效的替代品,具有不同的好處。

26.6.8.5正態分佈[蘭特。 dist.norm] 26.6.8.5.1類模板normal_distribution [rand.dist.norm.normal]

甲normal_distribution隨機數分佈根據概率密度函數

enter image description here

產生分佈的隨機 數x

參數μ和也被稱爲此分佈的均值和 標準偏差。

用於產生正態分佈號碼的最常見的算法是Box-Muller,但即使與算法有選擇和變化。

自由甚至明確地在標準中提到:

26.6.8隨機數分佈類模板[rand.dist] 。 。 。

3用於生成每個指定分佈的算法 是實現定義的 。

此一個goto選項是boost random

順便提及,作爲@Hurkyl指出:看來這兩個實現實際上是相同的:例如箱研磨機產生的值對,其中一個被返回,一個被緩存。這兩個實現僅在返回哪個值時不同。

此外,隨機數引擎被完全指定,並且將給予實施方式之間具有相同的序列,但照顧確實需要,因爲不同分佈採取也可以消耗不同量的隨機數據,以便產生他們的結果,這會使引擎不同步。

+0

我提供['minstd_rand0'](http://www.cplusplus.com/reference/random/minstd_rand0/)生成器... – DuckQueen

+0

繼Hurkyl點,是否有可能種子MSVC或GCC,以便他們會提供相同的結果? – DuckQueen

+0

@DuckQueen。不,但你可以製作一個交換返回的數字對的包裝。 –

7

與標準定義的PRN發生器不同,該標準必須爲相同的種子產生相同的輸出,該標準不保留分配的授權。從[rand.dist。一般]/3

用於生成每個指定分佈的算法都是實現定義的。

所以,即使分佈有密度函數的

enter image description here

形式實施如何,這起案件是由他們決定。

獲得便攜式發行版的唯一方法是自己寫一個或使用第三方庫。

相關問題