天天看點

大數量級組合數的計算方法

轉自:大數量級組合數的快速計算方法

由下面的組合數公式可以推導

大數量級組合數的計算方法

為了解決第二個效率的問題,我們對上式再做一步化簡。上式已經把連乘法變成了求和的線性運算,也就是說,上式已經極大地簡化了計算的複雜度,但是還可以進一步優化。從上式中,我們很容易看出右邊的3項必然存在重複的部分。現在我們把右邊第一項拆成兩部分:

大數量級組合數的計算方法

這樣,上式右邊第一項就可以被抵消掉,于是得到:

大數量級組合數的計算方法

上式直接減少了2m次對數計算及求和運算。但是這個公式還可以優化。對于上面公式裡的求和,當m < n / 2時,n-m是一個很大的數,但是當m>n/2時,n-m就會小很多。我們知道:

C(n,m) = C(n,n-m)

那麼通過這個公式,我們可以把小于n/2的m變為大于n/2的n-m再進行計算,結果是一樣的,但是卻能減少計算量。

當計算出ln(C(n,m))後,隻需要取自然對數,就可以得到組合數:

C ( n , m ) = e x p ( l n ( C ( n , m ) ) ) C(n,m) = exp(ln(C(n,m))) C(n,m)=exp(ln(C(n,m)))

這樣就完成了組合數的計算。

用這種方法計算組合數,如果隻計算ln(C(n,m))的話,n可以取到整型資料的極限值65535,

l n ( C ( 65535 , 32767 ) ) = 45419.6 ln(C(65535,32767)) = 45419.6 ln(C(65535,32767))=45419.6

而計算時間隻需要0.01ms。當然,如果要取對數得到最終的組合數的話,n的取值就不能達到這麼大了。但是這種算法仍然可以保證n取到1000以上,而不是開頭說的150這個極限值。例如:

C ( 1000 , 500 ) = 2.70288 e + 299 C(1000,500) = 2.70288e+299 C(1000,500)=2.70288e+299

計算時間仍然小于0.01ms。