隨機概率相關的面試題
1. 已知有個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中的數都是等概率的。
然後我們想辦法將1~49對映到1~10,顯然無法直接對映,我們只取1~40,對於41~49我們拋棄,這樣並沒有影響其隨機特性,因為1~40中的每一個數都是等概率出現的。
然後(1~4)→1,(5~8)→2,……。這樣就完成了rand10的功能。
只呼叫一次randA(),我們也無法實現randB(),所以也要呼叫兩次。
呼叫兩次共有4種結果,得到00,概率為p*p;得到01,概率為p*(1-p);得到10,概率為(1-p)*p;得到11,概率為(1-p)*(1-p)。
容易發現有兩種情形概率相等,01和10,那麼我們可以把這兩種情況對映為返回0或1,如果得到的是其它兩種情況,那麼我們就繼續再呼叫兩次randA();
簡單驗證一下,詳細證明請參考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個位置被選中。
。。。
只呼叫一次rand7()肯定無法達到目的。我們呼叫兩次rand7(),這樣我們可以隨機的得到1~49中的一個數,為什麼呢?
我們將49分成7段,1~7,8~14,15~21,22~28,29~35,36~42,43~49,第一次rand7()隨機選擇其中一段,第二次rand7(),隨機選擇段內的一個數,這樣我們得到的1~49中的數都是等概率的。
然後我們想辦法將1~49對映到1~10,顯然無法直接對映,我們只取1~40,對於41~49我們拋棄,這樣並沒有影響其隨機特性,因為1~40中的每一個數都是等概率出現的。
然後(1~4)→1,(5~8)→2,……。這樣就完成了rand10的功能。
int rand10()
{
int x;
do
{
x = (rand7()-1)*7+rand7();
}while(x > 40)
return (x-1)%4+1;
}
2. 有一個隨機生成器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()
{
int x1, x2;
do
{
x1 = randA();
x2 = randA();
}while(x1+x2 != 1)
return x1;
}
3. 程式的輸入包含兩個整數m和n,其中m<n。輸出是0~n-1範圍內m個隨機整數的有序列表,不允許重複。從概率的角度來說,我們希望得到沒有重複的選擇,其中每個選擇出現的概率相等。void generate(int m,int n)
{
int t = m;
for(int i = 0; i < n; i++)
if(Rand(0,n-1-i) < t) //即以t/(n-i)的概率執行下面的語句
{
printf("%d\n",i);
t--;
}
}
其中,Rand(a,b)隨機產生[a,b]範圍內的一個整數。
上述演算法源自Knuth的《計算機程式設計藝術 第2卷 半數值演算法》。Knuth 給出了概率上的證明,每個數選中的概率都是m/n,而且恰好選中m個數。
簡單驗證一下:
第0個數,被選中的概率是;
第1個數,被選中的概率是;
第2個數,被選中的概率是;
4. 給出一個n個元素的陣列,對所有元素隨機中排,也就是說,n!種可能的元素排列中隨機選出一種。void random_shuffle(int A[], int n)
{
for(int i = n-1; i > 0; i--)
{
swap(a[i], a[Rand(0, i)]);//即隨機選擇0~i中的一個元素
}
}
其中,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個位置被選中。
。。。
相關文章
- 面試概率題面試
- ES相關面試題面試題
- 集合相關面試題面試題
- 概率論04 隨機變數隨機變數
- Java 控制隨機數出現的概率Java隨機
- 面試遇到的redis相關問題面試Redis
- 【概率論】一維隨機變數隨機變數
- 概率論08 隨機變數的函式隨機變數函式
- TCP相關面試題總結TCP面試題
- [C++] STL相關面試題C++面試題
- Vue的一些相關面試題Vue面試題
- 面試題(五)常見vue相關面試題總結面試題Vue
- 隨機演算法 概率演算法隨機演算法
- 一道與 for 相關的字串面試題字串面試題
- Java中JVM相關面試題-整理JavaJVM面試題
- Unity3D相關面試題Unity3D面試題
- 系統設計 相關面試題面試題
- 【Java面試題】之泛型相關Java面試題泛型
- 面試中網路相關題目面試
- 面試題及相關參考答案面試題
- 雜題隨筆 10.31 兩道LIS相關的題
- 【Java面試題】如何回答GC相關問題Java面試題GC
- 概率的意義:隨機世界與大數法則隨機
- 一維隨機變數及其概率分佈隨機變數概率分佈
- 翻譯 | SpringBoot相關的面試問題Spring Boot面試
- iOS 記憶體管理相關面試題iOS記憶體面試題
- SSM框架相關基礎面試題整理SSM框架面試題
- 前端面試之js相關問題前端面試JS
- 分享10道Docker容器相關面試題!!!Docker面試題
- 概率論11 協方差與相關係數
- 面試題隨筆面試題
- Python中的隨機取樣和概率分佈(一)Python隨機概率分佈
- Python中的隨機取樣和概率分佈(二)Python隨機概率分佈
- Linkedin 面試題 | 複製隨機指標面試題隨機指標
- C++ const面試題和相關的解釋C++面試題
- 硬核 - Java 隨機數相關 API 的演進與思考(上)Java隨機API
- 深入淺出 Runtime(六):相關面試題面試題
- Hadoop/Spark相關面試問題總結HadoopSpark面試