我想计算
对于n
高达1000000
尽可能准确的值。这是一些示例代码。
from __future__ import division
from scipy.misc import comb
def M(n):
return sum(comb(n,k,exact=True)*(1/n)*(1-k/n)**(2*n-k)*(k/n)**(k-1) for k in xrange(1,n+1))
for i in xrange(1,1000000,100):
print i,M(i)
第一个问题是OverflowError: long int too large to convert
当n = 1101
. 这是因为comb(n,k,exact=True)
太大而无法转换为浮点数。然而,最终结果始终是一个数字0.159
。
我在如何计算具有大中间值的总和中提出了一个相关问题,但是由于三个主要原因,这个问题有所不同。
- 我要计算的公式不同,这会导致不同的问题。
- 从我给出的示例中可以看出,之前提出的使用 exact=True 的解决方案在这里没有帮助。编写我自己的梳子实现也行不通,因为我仍然需要执行浮点除法。
- 我需要计算比以前更大的值的答案,这会导致新的问题。我怀疑如果不以某种巧妙的方式对总和进行编码,就无法做到这一点。
一个不会崩溃的解决方案是使用
from fractions import Fraction
def M2(n):
return sum(comb(n,k,exact=True)*Fraction(1,n)*(1-Fraction(k,n))**(2*n-k)*Fraction(k,n)**(k-1) for k in xrange(1,n+1))
for i in xrange(1,1000000,100):
print i, M2(i)*1.0
n=1101
不幸的是,它现在太慢了,以至于我在合理的时间内 没有得到答案。
所以第二个问题是如何让它足够快地完成大型n
.