1. 程式人生 > >【轉載】隨機生成k個範圍為1-n的隨機數,其中有多少個不同的隨機數?

【轉載】隨機生成k個範圍為1-n的隨機數,其中有多少個不同的隨機數?

n) 不重復 nlog 並且 線性 一個 劃分 次數 com

來源:http://www.cnblogs.com/haolujun/archive/2012/11/11/2765102.html

假如現在讓你隨機生成k個範圍在1-n內的隨機數,那麽你能得到多少個不同的隨機數呢?剛開始想得時候,我認為當k<=n時,可以得到k個不同的隨機數,但是顯然這個想法錯了。做了個實驗在1-1024內隨機生成500個數,其中只有394個不同的數,隨機生成1000個數,其中有639個不同的數。

接下來是很枯燥的數學推導,如果你只是想看看最後的公式,那麽就看倒數第二行。如果你想看看推導過程那麽就看下去。下面說的東西用到了概率和組合數學中的線性常系數非齊次遞推關系。

現在我們想求一下,隨機生成k個範圍在1-n內的隨機數,能得到多少個不同的隨機數。

設我們隨機k次得到的的k個數字為x1,x2,......xk。

設E[i]為隨機i次得到的不重復數字個數的期望。

設p[i]為第i次隨機得到的xi與x1,x2,......,x[i-1]其中一個重復的概率。

設q[i]為第i次隨機得到的xi與x1,x2,......,x[i-1]中任何一個都不重復的概率。

那麽顯然p[i]=E[i-1]/n ,qi=(n-E[i-1])/n。

設Yi為指示器變量,Yi=1代表xi與x1,x2,......,x[i-1]中任何一個都不重復,Yi=0代表xi與x1,x2,......,x[i-1]其中一個重復。

那麽由E[i]的意義可得E[i]=sigma(1*q[j])+sigma(0*p[j])=sigma(1*q[j])=sigma((n-E[j])/n) {0<=j<=i-1}。

現在可以得到E[i]=i-(1/n)*sigma(E[j]) {0<=j<=i-1}。現在我們就得到了一個遞推關系式,並且我們知道E[0]=0,E[1]=1,我們可以用這個遞推關系式求E[i]。

當然我們並不僅僅止於此,我們繼續研究這個遞推關系式,求出一個通項公式來。

E[1]=1
E[2]=2-1/n * E[1]
E[3]=3-1/n * (E[1]+E[2])
E[4]=4-1/n * (E[1]+E[2]+E[3])
...
E[k]=k-1/n * (E[1]+E[2]+E[3]+......+E[k-1])

我們把用下面的式子減去上面的式子得到:

E[2]-E[1]=1-1/n * E[1]
E[3]-E[2]=1-1/n * E[2]
E[4]-E[3]=1-1/n * E[3]
...
E[k]-E[k-1]=1-(1/n)*E[k-1]

現在設S[i]=E[1]+E[2]+......+E[i],我們得到如下遞推式:S[k]-S[1]-S[k-1]=k-1-(1/n)*S[k-1]。

由於S[1]=1,我們得到:S[k]-(n-1)/n * S[k-1]= k。這是一個線性常系數非齊次遞推關系,對於這種遞推關系求通項公式,組合數學上說的很詳細。

通過解這個遞推關系,我們求得通項公式為S[k]=(1-2*n+n*n)*((n-1)/n)^(k-1)+(1-n)*n+n*k。

把S[k-1]帶入E[k]中得: E[k]=k-(1/n)*((1-2*n+n*n)*((n-1)/n)^(k-2)+(1-n)*n+n*(k-1))

當k趨向正無窮時,E[k]=k-(1/n)*(0+(1-n)*n+n*(k-1))=n,與我們的直覺是相符的。

現在,如果想得到n個不同的數,那麽k應該大概是多少呢?

我們假設一系列的試驗,C1,C2,C3,......,Ck中,Ci代表第i次試驗隨機生成的數字。

那麽我們可以對試驗進行階段劃分,階段i為:第i次試驗成功後的試驗開始,第i+1次試驗成功結束。階段i的試驗次數為X[i].

那麽總的試驗次數X=X[0] + X[1] + .... + X[n-1]。

第i個階段的每次試驗成功的概率為p=(n-i)/n,這是一個幾何分布,也就是說第i個階段的試驗次數的期望為1/p= n/(n-i)。

那麽總的試驗次數期望為:X= n/(n-0) + n/(n-1) + n/(n-2) + ...... + n/1 = n*(1 + 1/2 + 1/3 + ...... + 1/n) = n * Hn

其中Hn=(1 + 1/2 + 1/3 + ...... + 1/n) ~ log(n)。所以,可以如果要生成n個不同的數,那麽大概需要的試驗次數是nlogn級別的。

【轉載】隨機生成k個範圍為1-n的隨機數,其中有多少個不同的隨機數?