2017-02-13 79 views
2

有兩個球的容器,一個是紅色,另一個是黑色。 一個球繪製的每個時間和球的container.Drawing再次被置於完成n倍,其中1<=n<=10^6。我想找出圖紙紅球至少r的概率,其中0<=r<=n。例如,讓n=3r=2然後概率p可以被計算爲:如何查找給定容器中繪製球的概率?

p=(C(3,2)+C(3,3))/(2^3) 
p=(3+1)/8 
p=0.5 

其中C(n,r) = n!/(n-r)!r!。它也可以使用二項分佈來解決。 但是,給定的nr很難計算。

+0

發現你已經知道公式:C(N,R)= N /(! nr)!r!,爲什麼很難?你不知道如何編寫階乘函數? – algojava

+1

@algojava但是,對於給定的n值和r – Enigma

+0

是非常困難的,因爲n可以是10^6?如果n和r之間的差異很小,我可以幫助你編寫有效的代碼來計算二項式分佈。 – algojava

回答

4

您可以嘗試使用對數,即代替

P(r, n) = n!/((n-r)! * r! * r**n) 

計算只是

log(P(r, r)) = log(n!) - log((n-r)!) - log(r!) - r*log(n) 

所有階乘很容易可計算爲對數:

log(n!) = log(n) + log(n - 1) + ... + log(2) + log(1) 

當獲得log(P(r, n))所有你必須要做的就是取冪。作爲進一步的改進,你可以在情況下使用Stirling's approximation的階乘n很大:

n! ~ (n/e)**n * sqrt(2 * PI * n) 

左右(ln代表的自然對數)

ln(n!) ~ n * ln(n) - n - ln(n)/2 - ln(2 * PI)/2 

編輯:如果你正在尋找CDF累積分佈函數,隨機值小於或等於x的概率),它可以表示爲正規化不完全beta函數

https://en.wikipedia.org/wiki/Binomial_distribution

P(x <= k) = I(1 - p, n - r, r+1) 
p = 1/2 in your case 

的情況下,C++中,實現可以在Boost

+0

ooh,整齊,然後可以使用只是exp()函數 – Swift

+0

我不明白轉換爲對數的目的。如何加快對數的速度比直接乘數還要快? – ruakh

+0

@ruakh:對數實際上*減速*暗示,但允許您使用*大數字*:'1e6! == 8.2639 ... e5565708'當乘以數字時肯定是一個*溢出*,但是在合計對數時有一個合理的值:'ln(1e6!)== 12815518.38 ...' –