'简单'问题,计算二项式系数的最快方法是什么? - 一些线程算法?
我正在寻找提示:) - 不是实现:)
答案 0 :(得分:4)
我认为,最快的方法是从表中读取它们而不是计算它们。
你对使用双重表示的整数精度的要求意味着C(60,30)几乎都是大的,大约是1e17,所以(假设你想要所有m的C(m,n)到一些限制,并且所有n <= m),你的表只有大约1800个条目。至于填写表格,我认为Pascal的三角形是要走的路。
答案 1 :(得分:3)
提示:您希望尽可能少地进行乘法运算。公式为n! / (k! * (n-k)!)
。您应该执行少于2m
次乘法,其中m
是k
和n-k
的最小值。如果你想使用(相当)大数字,你应该使用一个特殊的类来表示数字(例如,Java有BigInteger)。
答案 2 :(得分:3)
根据下面的等式(来自wikipedia),最快的方法是将范围i = 1,k分割为线程数,给每个线程一个范围段,每个线程更新最终结果在一个锁。 “学术方式”是将范围分成任务,每个任务都要计算(n - k + i)/ i,然后无论你有多少线程,它们都会循环运行,要求下一个任务。第一是更快,第二是......学术。
编辑:进一步解释 - 在这两种方式中我们都有一些任意数量的线程。通常,线程数等于处理器核心数,因为添加更多线程没有任何好处。两种方式之间的区别在于这些线程正在做什么。
首先,每个线程给出N,K,I1和I2,其中I1和I2是1..K范围内的段。然后每个线程都拥有它所有的数据,因此它会计算结果的一部分,并在完成更新后得到最终结果。
第二种方式是给每个线程N,K,并访问从1到K计数的某个同步计数器。每个线程然后从这个共享计数器中获取一个值,计算结果的一部分,更新最终结果,和循环,直到计数器通知线程没有更多的项目。如果发生一些处理器内核比其他处理器内核更快,那么第二种方式将使所有内核最大限度地使用。第二种方式的下行是太多的同步,有效地阻止了20%的线程。
答案 3 :(得分:1)
如果最终结果可以在机器中本地表达,不涉及乘法/因子分解,很容易并行化,并且推广到BigInteger类型,那么这种方式永远不会溢出:
首先请注意,二项式系数满足以下条件:
。
这会产生一个直接的递归来计算系数:基本情况是和,两者都是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)