二项系数

时间:2010-11-23 12:49:16

标签: multithreading algorithm complexity-theory binomial-coefficients binomial-cdf

'简单'问题,计算二项式系数的最快方法是什么? - 一些线程算法?

我正在寻找提示:) - 不是实现:)

5 个答案:

答案 0 :(得分:4)

我认为,最快的方法是从表中读取它们而不是计算它们。

你对使用双重表示的整数精度的要求意味着C(60,30)几乎都是大的,大约是1e17,所以(假设你想要所有m的C(m,n)到一些限制,并且所有n <= m),你的表只有大约1800个条目。至于填写表格,我认为Pascal的三角形是要走的路。

答案 1 :(得分:3)

提示:您希望尽可能少地进行乘法运算。公式为n! / (k! * (n-k)!)。您应该执行少于2m次乘法,其中mkn-k的最小值。如果你想使用(相当)大数字,你应该使用一个特殊的类来表示数字(例如,Java有BigInteger)。

答案 2 :(得分:3)

根据下面的等式(来自wikipedia),最快的方法是将范围i = 1,k分割为线程数,给每个线程一个范围段,每个线程更新最终结果在一个锁。 “学术方式”是将范围分成任务,每个任务都要计算(n - k + i)/ i,然后无论你有多少线程,它们都会循环运行,要求下一个任务。第一是更快,第二是......学术。

alt text

编辑:进一步解释 - 在这两种方式中我们都有一些任意数量的线程。通常,线程数等于处理器核心数,因为添加更多线程没有任何好处。两种方式之间的区别在于这些线程正在做什么。

首先,每个线程给出N,K,I1和I2,其中I1和I2是1..K范围内的段。然后每个线程都拥有它所有的数据,因此它会计算结果的一部分,并在完成更新后得到最终结果。

第二种方式是给每个线程N,K,并访问从1到K计数的某个同步计数器。每个线程然后从这个共享计数器中获取一个值,计算结果的一部分,更新最终结果,和循环,直到计数器通知线程没有更多的项目。如果发生一些处理器内核比其他处理器内核更快,那么第二种方式将使所有内核最大限度地使用。第二种方式的下行是太多的同步,有效地阻止了20%的线程。

答案 3 :(得分:1)

如果最终结果可以在机器中本地表达,不涉及乘法/因子分解,很容易并行化,并且推广到BigInteger类型,那么这种方式永远不会溢出:

首先请注意,二项式系数满足以下条件:

binomnk

这会产生一个直接的递归来计算系数:基本情况是binomrrbinomr0,两者都是1.

suballs的单个结果是整数,如果\ binom {n} {k}可以用int表示,它们也可以;因此,溢出不是一个问题。

通过实现,递归导致重复的子句和指数运行时。

这可以通过缓存中间结果来解决。有 n ^ 2个子问题,可以在O(1)时间内组合,产生O(n ^ 2)复杂度界限。

答案 4 :(得分:0)

此答案使用 Python 计算二项式:

def h(a, b, c):
    x = 0
    part = str("=") 
    while x < (c+1):
        nCr = math.comb(c,x)
        part = part+'+'+str(int(a**(c-1))*int(b**x)*int(nCr)+'x^'+str(x)
        x = x+1
    print(part) 
    
    h(2,6,4)