2009-12-31 177 views
9

你有一個有偏倚的隨機數發生器,產生1概率爲p,0爲概率(1-p)。你不知道p的價值。使用它可以產生一個無偏的隨機數發生器,其產生1的概率爲0.5,0的概率爲0.5。無偏隨機數發生器使用偏倚的隨機數發生器

注意:這個問題是從介紹由Cormen,Leiserson,維斯特,斯坦算法的練習題(CLRS)

+1

我猜測答案與標準方法使用偏置發生器有關,並且一次作爲反函數,這樣你就有一次0的概率,第二次迭代的0(1-p)概率,並混合這兩個結果來平衡分配。我不知道背後的確切數學。 – 2009-12-31 19:50:13

+0

埃裏克 - 是的,如果你做了(蘭特()+(1蘭特()))/ 2,你可以合理地期望獲得一個無偏見的結果。請注意,在上面你應該調用rand()兩次,否則你總是得到。5 – JohnE 2009-12-31 19:57:21

+0

@JohnE:基本上這就是我的想法,但是這不會讓你得到一個0或1的直線,這是要求的。我認爲保羅用他的回答擊中了頭部。 – 2009-12-31 20:02:48

回答

17

事件(P)(1-p)和(1-P)。 (p)是等概率的。將它們分別作爲0和1,並丟棄另外兩對結果,得到一個無偏的隨機生成器。

在代碼中,這是爲做容易,因爲:

int UnbiasedRandom() 
{ 
    int x, y; 

    do 
    { 
     x = BiasedRandom(); 
     y = BiasedRandom(); 
    } while (x == y); 

    return x; 
} 
+3

完美。從歷史上看,這種設備是由於我們都熟悉的馮諾依曼(可能沒有意識到)。 – jason 2009-12-31 20:19:35

+0

如果偏差本身在一段時間內變化,這是否仍然有效? – 2501 2016-09-20 21:50:05

2

您需要從RNG畫對值直到你得到不同值的序列,即,零後面緊跟着一個或一個零。然後,您獲取該序列的第一個值(或最後一個,無關緊要)。

(只要引出的一對或者是兩個零或兩個1即重複)這背後的數學很簡單:0然後1序列具有非常相同的概率爲1,則零序。通過總是將這個序列的第一個(或最後一個)元素作爲新的RNG的輸出,我們有機會得到一個零或一個。

1

下面是一種方法,可能不是最有效的。咀嚼一堆隨機數,直到得到[0 ...,1,0 ...,1]形式的序列(其中0 ...是一個或多個0)。計數0的數量。如果第一個序列較長,則生成一個0,如果第二個序列較長,則生成一個1.(如果它們相同,則再試一次。)

這就像HotBits從放射性生成隨機數粒子衰變:

由於任何給定衰變的時間是隨機的,因此兩個連續衰變之間的間隔也是隨機的。我們所做的是測量一對這樣的間隔,並根據兩個間隔的相對長度發出一個零位或一位。如果我們測量兩個衰變相同的間隔,我們丟棄測量並再次嘗試

HotBits: How It Works

4

歸因於馮·諾伊曼同時獲得兩個比特的特技,具有01對應於0和10到1,重複00或11已經出現。使用此方法需要提取以獲取單個位的位的預期值爲1/p(1-p),如果p特別小或大,則該位可能會變得非常大,因此值得問一問該方法是否可以改進,特別是因爲它是它顯然會拋出很多信息(全部是00和11)。

谷歌搜索「馮·諾伊曼特技偏置」產生this paper,開發針對該問題的更好的解決方案。這個想法是,你仍然需要一次兩位,但如果前兩次嘗試只產生00秒和11秒,你把一對0作爲單個0和一對1作爲一個1,並且應用馮諾依曼的技巧對這些對。如果這也不起作用,那麼在這個級別的對上繼續類似的組合,等等。

此外,本文將此發展爲從偏置源生成多個無偏位,本質上使用兩種不同的方法從位對生成位,並給出一個草圖,表明這是最優的,原始序列在其中熵的位數。

4

produce an unbiased coin from a biased one的程序首先歸因於Von Neumann(一個在數學和許多相關領域做了大量工作的人)。程序非常簡單:

  • 投擲硬幣兩次。
  • 如果結果一致,重新開始,忘記兩個結果。
  • 如果結果不同,請使用第一個結果,忘記第二個結果。

這個算法工作的原因是因爲越來越HT的概率p(1-p),這是與獲取TH (1-p)p。因此兩個事件同樣可能。

我也在讀這本書,它會詢問預計的運行時間。兩次投擲不相等的概率爲z = 2*p*(1-p),因此預計運行時間爲1/z


前面的例子看起來令人鼓舞的(畢竟,如果你有一個偏見硬幣的p=0.99偏見,你需要把你的硬幣大約50倍,這是沒有那麼多)。所以你可能會認爲這是一個最佳算法。可悲的是,事實並非如此。

這是它與Shannon's theoretical bound(圖片取自answer)的比較。它表明算法很好,但遠不是最優的。

enter image description here

你能想出的改善,如果你會考慮HHTT將通過該算法被丟棄,但其實它具有相同的概率TTHH。所以你也可以在這裏停下來並返回H.HHHHTTTT也是如此。使用這些情況可以改善預期的運行時間,但不會使其在理論上最佳。


而在最後 - Python代碼:

import random 

def biased(p): 
    # create a biased coin 
    return 1 if random.random() < p else 0 

def unbiased_from_biased(p): 
    n1, n2 = biased(p), biased(p) 
    while n1 == n2: 
     n1, n2 = biased(p), biased(p) 

    return n1 

p = random.random() 
print p 

tosses = [unbiased_from_biased(p) for i in xrange(1000)] 
n_1 = sum(tosses) 
n_2 = len(tosses) - n_1 
print n_1, n_2 

這是不言自明的,這裏有一個例子結果:

0.0973181652114 
505 495 

正如你看到的,但是我們有0.097的偏差,我們得到大約相同數量的10

+0

如果偏差本身隨時間變化,這是否仍然有效? – 2501 2016-09-20 21:50:28

+0

@ 2501不,它不是 – 2016-09-20 22:48:39

+0

感謝您的回覆。顯然,概率不再一樣了。我想知道現實生活中的生成器如何處理這個問題。 – 2501 2016-09-21 12:53:53