2015-05-31 73 views
5

我寫了一個小的代碼,以確保我可以從一個非常廣泛的範圍得到的隨機數,恩。 [0,10^36),因爲我將在稍後使用這些寬範圍。隨機數是不是真的均勻分佈

我的代碼如下:

#include <iostream> 
#include <cmath> 
#include <random> 
#include <chrono> 

int main() 
{ unsigned seed = std::chrono::system_clock::now().time_since_epoch().count(); 
    double expo = pow(10,36); 
    std::uniform_real_distribution<double> dist(0,expo); 
    std::mt19937_64 rng(seed); 
    for (int i=0; i<10; i++) 
     std::cout << dist(rng) << std::endl; 
    return 0; 
} 

而下面是輸出的一個例子:

6.75507e+035 
4.01129e+035 
6.85525e+035 
8.85896e+035 
3.1455e+035 
3.04962e+035 
5.48817e+035 
3.54502e+035 
2.24337e+035 
2.23367e+035 

正如你所看到的,隨機數都是真正貼近上端點給定的時間間隔。我嘗試了很多次運行程序,也將10個數字增加到了100,但隨機數總是接近間隔的上端點(指數35,有時是34)。

由於我已經使用std::uniform_real_distribution,我期望有也有時號碼在範圍[0,1000]例如。我不認爲這是一個統一的分配。這是對我來說重要的是隨機數,不僅接近上終點,因爲我將使用後的隨機數的if語句:

if (random_number == 0) 
    //do some operations 

而上端點將被實際用作率,發生的事情。但似乎有些時候隨機數不可能爲零。

我不知道爲什麼會這樣,真的希望任何想法或幫助。

(Eclipse的4.4.1,Windows 7中)

+0

如果'std :: uniform_real_distribution dist(0,1000)(rng)'返回(確切地)1000.0,那麼在您的實現中存在一個錯誤並且應該報告它,因爲間隔應該是半關閉的:'[0,1000)'。返回0是可能的,但概率是微觀的,可能小於一個四捨五入。 – rici

回答

12

正如你所看到的,隨機數都非常接近上 端點給定區間。

不,他們不是。此舉一出,例如:

2.23367e+035 

注意,在範圍[0, 1e36],小範圍[1e35, 1e36]是小範圍[0, 1e35] 9倍,因此具有均勻的分佈,你可以期望看到這些數字經常是9次。你會看到不時指數爲34的數字,但指數較低的指數非常罕見。

+2

沒錯!我沒有想過......所以這意味着它是一個統一的分佈。 謝謝你本傑明! – azish

4

本傑明·林德利的回答是好。我想補充一點,你可能正在尋找一種不同的分配方式,而不是一種統一的分配方式。你可以寫這樣的:

#include <iostream> 
#include <cmath> 
#include <random> 
#include <chrono> 

int main() 
{ 
    unsigned seed = std::chrono::system_clock::now().time_since_epoch().count(); 
    std::uniform_real_distribution<double> dist(0, 36); 
    std::mt19937_64 rng(seed); 
    for (int i = 0; i < 20; i++) 
    { 
     std::cout << pow(10, dist(rng)) << std::endl; 
    } 
    return 0; 
} 

那個節目給了我下面的輸出:

7.26972e+027 
5.97e+010 
3.50003e+034 
3.42446e+021 
2.93422e+035 
111.724 
2.73858e+019 
55641.4 
4.18253e+019 
7.47441e+007 
9.2706 
7.45588e+009 
3.26219e+007 
5.6794e+027 
4.67289e+026 
4.24672e+014 
3.97334e+010 
14.7511 
2.65037e+022 
85279.3 
+0

這是一個好主意,但正如我前面提到的,我應該稍後使用高端端點作爲費率,所以我不能更改它。 :/但無論如何,謝謝! – azish

+0

我沒有更改上端點,仍然是10^36。我不小心將低端從0改爲1。 –

+0

你是對的。但是我的代碼中的速率是,例如對於random_number = 1,生成此隨機數的概率爲1/10^36。您的代碼中的這種概率是1/35 * 1/10^dist(rng)。因爲實際上這個概率是我的目的,而不是隨機數本身,所以我不能使用你的代碼,儘管如果我沒有考慮概率的限制,我相信這是一個有趣的想法。 – azish

1

如果你看看形勢的數學,它更可能是一些將有李氏指數10^35因爲在每個範圍可能數量:

  • 9*10^34不同的號碼範圍[1*10^35,1*10^36)
  • 有範圍9*10^33不同數量[1*10^34,1*10^35)
  • 1000不同的號碼範圍[1,1000]

所以你可以看到,這是10次,數量更可能有指數10^3510^34並且9*10^32倍數的指數10^35比在[1,1000]範圍內的可能性更大。

+0

是的,那是我錯過的觀點!謝謝Brendon! – azish