隨機概率問題全集

2021-06-18 04:36:43 字數 1696 閱讀 4061

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

只呼叫一次rand7()肯定無法達到目的。我們呼叫兩次rand7(),這樣我們可以隨機的得到1~49中的乙個數,為什麼呢?

我們將49分成7段,1~7,8~14,15~21,22~28,29~35,36~42,43~49,第一次rand7()隨機選擇其中一段,第二次rand7(),隨機選擇段內的乙個數,這樣我們得到的1~49中的數都是等概率的。即」(rand7()-1)*7+rand7()「。然後我們想辦法將1~49對映到1~10,顯然無法直接對映,我們只取1~40,對於41~49我們拋棄,這樣並沒有影響其隨機特性,因為1~40中的每乙個數都是等概率出現的。

然後(1~4)→1,(5~8)→2,……。這樣就完成了rand10的功能。

int rand10()

while(x > 40)

return x%10+1;

}

注:由朋友問為什麼用while(x>40)而不用while(x>10)呢?原因是如果用while(x>10)則有40/49的概率需要迴圈while,很有可能死迴圈了。

問題:有乙個隨機生成器randa(),以p的概率返回0,1-p的概率返回1,利用這個randa()構造randb(),使randb()等概率的返回0和1,即0.5的概率返回0,0.5的概率返回1。

只呼叫一次randa(),我們也無法實現randb(),所以也要呼叫兩次。呼叫兩次共有4種結果,得到00,概率為p*p;得到01,概率為p*(1-p);得到10,概率為(1-p)*p;得到11,概率為(1-p)*(1-p)。容易發現有兩種情形概率相等,01和10,那麼我們可以把這兩種情況對映為返回0或1,如果得到的是其它兩種情況,那麼我們就繼續再呼叫兩次randa();

int randb()

while(x1+x2 != 1)

return x1;

}

問題:給出乙個n個元素的陣列,對所有元素隨機中排,也就是說,n!種可能的元素排列中隨機選出一種。

void random_shuffle(int a, int n)

}

其中,rand(a,b)隨機產生[a,b]範圍內的乙個整數。

簡單驗證一下,詳細證明請參考knuth的《計算機程式設計藝術 第2卷 半數值演算法》。

當對於第n-1個位置,swap(a[n-1], a[rand(0, n-1)]),使得每乙個元素出現在位置n-1的概率都是1/n;

再考慮第n-2個位置,每個元素出現在第n-2個位置上的概率是(n-1)/n * 1/(n-1) = 1/n,即在第n-1個位置沒有被選中,然後在第n-2個位置被選中;

再考慮第n-3個位置,每個元素出現在第n-3個位置上的概率是(n-1)/n * (n-2)/(n-1) * 1/(n-2) = 1/n,在第n-1和第n-2個位置都沒有被選中,然後在第n-3個位置被選中。

。。。

問題:程式的輸入包含兩個整數m和n,其中m

void generate(int m,int n)

}

簡單驗證一下:

不等概率隨機

實現乙個,按 不同 權重 隨機元素的實現,如 a的權重為1,b的權重為2,那麼 隨機元素的時候 b的出現概率為 2 3 a出現的概率為 1 3。不等概率 權重 隨機 param sampledatamap 樣本資料,key 資料,value 資料的權重 return public static lo...

海量資料等概率隨機選取問題

1 問題定義可以簡化如下 在不知道檔案總行數的情況下,如何從檔案中隨機的抽取一行?首先想到的是我們做過類似的題目嗎?當然,在知道檔案行數的情況下,我們可以很容易的用c執行庫的rand 函式隨機的獲得乙個行數,從而隨機的取出一行,但是,當前的情況是不知道行數,這樣如何求呢?我們需要乙個概念來幫助我們做...

按概率隨機選取

據我了解,random.choice seq 是等概率選取乙個,不是我想要的。而numpy.random.choice seq,p,k 是按概率隨機重複選取多個,這正是我想要的。但是,我不想為這麼乙個函式引入巨大的numpy庫,所以打算自己實現乙個按概率隨機選取的函式。特此將 記錄如下 import...