2013-04-16 3 views
3

는 I는 최종 결과가 숫자하지큰 중간 값 합을 계산하는 방법

S = n + m - \sum_{k=1}^{n} k^{k-1} \binom{n}{k} \frac{(n-k)^{n+m-k}}{n^{n+m-1}}

두 값이 (1000)까지 범위의 정수를 되와 N미터 대해 계산하고자 n보다 훨씬 크지 만 중간 값은 너무 커서 파이썬이 대처할 수 없습니다. 어떻게 이것을 해결할 수 있습니까?

다음과 같이 함수를 정의합니다.

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 얻을 오류는, 예를 들어, 문제가 scipy의 comb 정의처럼

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

죄송합니다. LaTeX은 SO에서 작동하지 않습니다. (실제로 시도했으면 좋겠지 만.) 정말로 그 질문을 다시 형식화하여 조금 더 읽기 좋습니까? – Makoto

+4

대용량의 파이썬에 너무 큰 정수가 있습니까? 확실합니까? –

+1

파이썬은 임의의 크기의 정수를 처리 할 수 ​​있습니다. 넌 멍청한거야? –

답변

4

이 보인다. 내가 만든 버전을 제공 할 때, 잘 작동 : (약 1.5 초)

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) 

결과 :

1844 

을 대안으로 자신의 comb를 쓰기에, 옵션 exact에 대한에 True을 전달 시도 인수는 comb입니다. 너는 그렇지 않으면 다시 물건을 엉망 수 있습니다 플로트를 얻을거야 것 같습니다.

+0

정확하게 = true를 추가하면 문제가 해결 될뿐만 아니라 속도도 빨라집니다! 그런 다음 __future__ import division을 추가 할 수 있으며 여전히 작동합니다. 저에게 빗살처럼 보이는 버그입니다. – Anush

+0

나는 할 것이다. .. 나는 빨리 타이핑하지 않는 사람들을 위해 적어도 한 시간 동안 질문을 공개하는 것이 예의라고 생각한다. :) – Anush

2

scipy.misc.comb은이 경우 하나의 부동 소수점 수인 ndarray을 반환합니다. 나머지 계산은 정수 (결국 파이썬 < 3의 긴 정수)로 수행됩니다. 부동 소수점 숫자에 int를 곱하면 파이썬은이 값을 float로 변환하려고 시도하지만 99 ** 199 ~ 1e397은 Python float (64 비트)에 맞지 않으므로 오류가 발생합니다.

해결 방법은 comb에 대한 인수로 exact=True을 전달하는 것입니다. 그런데 []sum 안에 없앨 수 있습니다. 이렇게하면 내부 목록이 만들어지지 않으므로 더 빠르고 효율적으로 메모리를 할당해야합니다 (rangexrange의 차이점과 유사 함). 부동 소수점 숫자를 더하는 경우 (여기서는 필요 없음) sum보다 math.fsum (정확한 부동 소수점 합계)을 사용하는 것이 훨씬 좋습니다.