面試題:等概率生成器


問題一

已知一隨機發生器,產生0的概率是p,產生1的概率是1-p,現在要你構造一個發生器,使得它構造0和1的概率均為1/2;

構造一個發生器,使得它構造1、2、3的概率均為1/3;…, 
構造一個發生器,使得它構造1、2、3、…n的概率均為1/n,要求復雜度最低。

解決方法:

原始的隨機數生成器,生成0 的概率為p,生成1的概率為1-p,那么怎么構造才能使得生成0和1的概率相等呢。或者說有兩個獨立的事件的概率是相等呢?

這樣來做一下,讓該隨機數生成器生成兩個數,那么序列是00,01,10,11概率分別為 p*p,p(1-p),(1-p)p,(1-p)*(1-p)

很明顯,這四種情況中存在兩個獨立的事件概率是相等。也就是01和10,那么我把01看成是0,10看成是1,那么他們輸出的概率均為p(1-p),其他的情況舍棄。這樣就得到了0和1均等生成的隨機器了。

這種解法可以推廣到n個數的情況,我們知道,取n個隨機數發生器,存在n個概率相同的獨立事件,我們只使用這n個事件就得到1/n的概率了。例如n=3,有8中情況000,001,010,011,100,101,110,111,其中001,010,100的概率都是p^2*(1-p)。

問題二:已知有個rand7()的函數,返回1到7隨機自然數,讓利用這個rand7()構造rand10() 隨機1~10。

解決方案:這個問題和上個問題不同的是,這里產生的序列,要變成和的形式或者其他的形式,那么概率就會發生變化了。

如果能夠得到一組等概率的數,不管是什么數,只要等概率而且個數大於10,那么問題就可以解決了。

發現(rand7()-1)*7+rand7(),可以等概率的生成1到49。

呵呵,這不就得了,只要把11-49砍掉就可以了。不過這樣的效率比較低。可以砍掉41-49,然后在把1-40映射到1-10(例如模10),那么問題也就解決了。

問題三:調用RANDOM(0, 1)實現RANDOM(a, b)

解決方案:這里的RANDOM(0, 1)是指等概率產生0或1,顯然,RANDOM(a, b) = a + RANDOM(0, b-a)

可以這樣做:

         1,取 n=b-a+1,取最小的正整數m,使得 2^m >= n
         2,調用RANDOM(0,1),輸出m-bit位整數N   (  N >= 0 and N <= 2^m-1)
         3,  if   N >=0  and N <= b-a
                      then return a+N     
                else 重新執行步驟 2

 

附:

// 問題一代碼實現

int MyRand()
{
    int a = randP(), b = randP();
    if(a != b)  return a;
    return -1;
}

//問題三的一種遞歸實現,n不是2的冪時有誤差

int random( a, b )
{
   if( a == b )
     return a;
   if( random( 0, 1 ) )
     return random( a, (a+b)/2 );
   else
     return random( (a+b)/2 + 1, b );
}

 

 

參考鏈接:

1. CSDN_geekster-一些常見的概率生成器的題目

2. CSDN_chfe910-[面試題][數學與概率]設計隨機數生成器

3. CSDN_ShenYounger-通過有偏概率0/1生成器,生成無偏概率0/1生成器

4. 博客園-用random(0,1)來實現random(a,b),並估計運行時間.


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM