二項式係數
回答
根據下面的公式(來自wikipedia),最快的方法是將範圍i = 1,k分割爲線程數,爲每個線程分配一個範圍段,並且每個線程更新鎖中的最終結果。 「學術方式」是將範圍分成任務,每個任務都要計算(n-k + i)/ i,然後不管你有多少個線程,它們都運行在一個循環中,要求下一個任務。首先是更快,其次是...學術。
編輯:進一步解釋 - 在這兩個方面,我們有線程的一些任意數量。通常線程的數量等於處理器內核的數量,因爲添加更多線程沒有好處。兩種方式之間的區別在於這些線程正在做什麼。
在第一種方式中,給出每個線程N,K,I1和I2,其中I1和I2是範圍1..K中的線段。然後每個線程都擁有它所需的所有數據,因此它會計算其結果的一部分,並在完成時更新最終結果。
第二種方法是給每個線程賦予N,K,並訪問一些從1到K計數的同步計數器。然後每個線程從該共享計數器中獲取一個值,計算結果的一部分,更新最終結果,並在此循環,直到計數器通知線程沒有更多的項目。如果發生某些處理器內核比其他處理器內核速度更快,那麼第二種方式將使所有內核達到最大使用狀態。第二種方式的下滑是太多的同步,例如20%的線程總是有效地阻止。
提示:你想要做的少乘法越好。公式是n!/(k! * (n-k)!)
。您應該少於2m
乘法,其中m
是k
和n-k
中的最小值。如果你想使用(相當)大的數字,你應該使用一個特殊的類來表示數字(例如Java有BigInteger)。
好吧,我認爲最快的方法是從表中讀取它們而不是計算它們。因爲使用雙重表示法對整數精度的要求意味着C(60,30)幾乎都太大,大約在1e17,所以(假設你想要C(m,n)到一定的限制,並且所有的n < = m),你的表格只有大約1800個條目。至於填補我認爲帕斯卡的三角形是要走的路。
這裏的,如果最後的結果是表達本身的機器,從來沒有溢出的方式,不涉及乘法/因式分解,容易被並行化,並推廣到BigInteger的類型:
首先要注意的是,二項式係數滿足以下:
。
這產生了一個簡單的遞歸來計算係數:基礎案例是和,兩者都是1。
subcalls的單個結果是整數,如果\ binom {n} {k}可以用int表示,它們也可以;所以,溢出不是一個問題。
天真地執行,遞歸導致重複的subcalls和指數運行時。
這可以通過緩存中間結果來解決。有 n^2子問題,它們可以在O(1)時間內組合,產生一個O(n^2)複雜性界限。
- 1. 二項式係數
- 2. 二項式係數
- 3. 二項式係數模142857
- 4. LISP二項式係數,階乘
- 5. 並行計算二項式係數
- 6. 計算二項式係數的算法
- 7. 具有大二項式係數的繪圖函數
- 8. 使用一維數組的二項式係數
- 9. 如何計算大數的二項式係數
- 10. RStudio .rd文件 - 二項式變係數的幫助文件
- 11. 使用鏈接列表的Java遞歸二項式係數
- 12. 計算大二項式係數的總和
- 13. 二項式係數;不能解析爲變量
- 14. 更多的二項式係數和FORTRAN 95
- 15. 使用記憶法計算python中的二項式係數
- 16. 不同的二項式係數算法的效率比較
- 17. 算法二項式係數(NCR)在Ruby中
- 18. 在LISP中使用尾遞歸的二項式係數
- 19. 二項式
- 20. 二項式圖
- 21. Fit beta二項式
- 22. 乘以二項式
- 23. 二項式係數函數C++不正確的答案n> 13
- 24. 將多項式轉換爲二項式 - 數千列
- 25. Python中的Beta二項式函數
- 26. 數學:重整多項式係數
- 27. 在C中求解多項式(4,二階)的系統
- 28. 概率一系列二項式事件的統計
- 29. 裝配x86/C遞歸二項式係數Segfault /打印帕斯卡三角形
- 30. 多項式展開:分離多項式係數和x
不準確,僅限於有限範圍的輸入?我認爲你應該擴大一點你的要求。例如,如果您只對機器大小的整數感興趣,那麼任意大小的整數就是另一回事。 – 2010-11-23 13:06:11
那麼好吧,讓它限制爲java雙打? :) - 並在整數水平上準確 – Skeen 2010-11-23 13:13:10