我想计算
n ≥ m ,两个值的整数范围最大为1000.最终结果是一个数字不比 n 大很多但是对于python来说,中间值太大了。你怎么解决这个问题?
我将函数定义如下。
from scipy.misc import comb
def S(n,m):
return n+m-sum([k**(k - 1)*comb(n, k)*(n - k)**(n + m - k)/n**(n + m - 1) for k in xrange(1,n+1)])
例如,我为n=m=100
获得的错误是
RuntimeWarning: overflow encountered in multiply
return n+m-sum([k**(k - 1)*comb(n, k)*(n - k)**(n + m - k)/n**(n + m - 1) for k in xrange(1,n+1)])
[...]
OverflowError: long int too large to convert to float
答案 0 :(得分:4)
似乎问题出现在scipy的comb
定义中。当我提供自制版本时,它可以正常工作:
import math
def choose(n,k):
return math.factorial(n) / (math.factorial(k)*math.factorial(n-k))
comb = choose
def S(n,m):
return n+m-sum([k**(k - 1)*comb(n, k)*(n - k)**(n + m - k)/n**(n + m - 1) for k in xrange(1,n+1)])
print S(1000,1000)
结果(约1.5秒):
1844
作为编写自己的comb
的替代方法,请尝试将True
的可选exact
参数传递给comb
。看起来你会得到一个漂浮,否则可能会搞砸了。
答案 1 :(得分:2)
scipy.misc.comb
返回一个浮点数的ndarray
。其余的计算是用整数完成的(最终在Python中的长整数< 3)。当浮点数乘以int时,Python会尝试将其转换为浮点数,但99 ** 199~1e397不适合Python浮点数(64位),因此会引发错误。
解决方案是将exact=True
作为参数传递给comb
。顺便说一下,你可以删除[
里面的]
和sum
:这可以避免内部列表的创建,因此它应该更快,内存效率更高(它类似于range
和xrange
)。如果您碰巧正在添加浮点数(此处不需要),那么使用math.fsum
(精确的浮点值和)比sum
要好得多。