2011-03-29 99 views
0

其實,我有幾個交織問題。 (如果它很重要,我使用C#)。縮放Int內統一的隨機範圍變成雙數

首先。我有一個在UInt32範圍內產生隨機數的prng,從0到UInt32.Max(含)。我想盡可能保持一致性。 (a,b),雙重範圍(如[0,1],[0,1),(0,1),[-2,4],( - 10,10))?

我很關心以下內容。我有4 294 967 296個成果。它小於[0,1]的雙數範圍中的數字 - 2^53。所以我從2位數字構造了4 294 967 296-ary數字,這在[0,4294967295 * 4294967296 + 4294967295]中是隨機的和統一的。這個最大值大於1^2^53,所以如果有人把它扔掉了,重新計算,使用mod 2^53並且得到統一的數字,例如[0,1]。在這裏,我必須將最大值表示爲double(假設沒有Int64類型) - 它有沒有什麼缺點?現在,如果我想得到[0,1),我認爲結果的數目是(2^53) - 1。加上最後的結果1 /(2^53)將產生隨機雙0,1]。爲了得到(0,1),我考慮(2^53) - 2個新的結果並將1 /(2^53)加到0爲基礎的結果。得到接近或等於整個雙倍範圍的雙倍範圍?即使我構造如上所述的n元數,它可能會變得比Double.Max大。可能有些位移/位掩碼方法有可能嗎?

其次。現在在[0,1)中有雙重結果,可以得到[Double.Min,Double.Max]範圍嗎?有多少個雙數?如果有完整的雙倍範圍prng,獲得UInt範圍的最佳方式是什麼?直接映射或直接映射到[0,1]之前?

三。我發現這個代碼(http://www.math.sci.hiroshima-u.ac.jp/~m-mat/MT/MT2002/CODES/mt19937ar.c):

/* generates a random number on [0,1) with 53-bit resolution*/ 
double genrand_res53(void) 
{ 
    unsigned long a=genrand_int32()>>5, b=genrand_int32()>>6; 
    return(a*67108864.0+b)*(1.0/9007199254740992.0); 
} 

爲什麼A和B轉移到5和6,爲什麼之後a * 67108864.0 + b是統一的?

謝謝。

回答

1

良好的隨機數發生器在所有位置產生隨機位。某些類別的窮程序在低階位中產生較差的隨機性。因此,如果您需要53位並生成64位,那麼您希望丟棄11位最低位 - 在您發佈的示例代碼中,5位來自一位數字,5位來自另一位數字。現在你有一個26位數字和一個27位數字; 2^26是67108864,2^53是9007199254740992,這應該解釋爲什麼這些常量用於將這些數字縮放到[0,1)。 (這是一個混合基數:第一位數字爲67108864-ary,第二位數字爲134217728-ary)。

(原因53位常被使用的原因是它使得數字在減法時是對稱的 - 否則,當你從1中減去它們時,2^-53和2^-64之間的值將消失。)

另外,當你有太多的位時,你不應該重新取樣 - 只是丟掉剩餘的位少於一個)。

無論如何,明顯的方法給你[0,1)。如果你想(0,1)即1 - [0,1)。如果你想(0,1),如果你同時得到a = 0和b = 0,再次採樣。如果你想[0,1],請注意獲得1的概率是1(2^53 + 1),否則你有[0,1]。你可以通過在[0,1)中得到一個隨機數並檢查它是否爲零來近似,如果是,則選擇1作爲答案,否則從[0,1)再次選擇。無論如何,你的隨機數發生器可能沒有足夠長的時間段。

相關問題