简体   繁体   English

如何让我的递归选择 k 函数在 Python 中处理大数字?

[英]How can I make my recursvie n choose k function work with big numbers in Python?

The title says it all, my function isn't working with big numbers.标题说明了一切,我的函数不适用于大数字。 For example (1000 C 800) would crash it.例如 (1000 C 800) 会使它崩溃。

def choose(n, k):
    if n == k:
        return 1
    elif k == 0:
        return 1
    else:
        return choose(n-1, k) + choose(n-1, k-1)
def choose(n, k):
  dp = [[0 for x in xrange(k+1)] for x in xrange(n+1)]

  for i in xrange(n+1):
    for j in xrange(k+1):
      if j > i:
        continue
      if j == 0:
        dp[i][j] = 1
      elif j == i:
        dp[i][j] = 1
      else:
        dp[i][j] = dp[i-1][j-1] + dp[i-1][j]

  return dp[n][k]

You could use dynamic programming to avoid calculating the same subproblems over and over again.您可以使用动态规划来避免一遍又一遍地计算相同的子问题。 It comes at the cost of some space.这是以一些空间为代价的。

To avoid repeated recalculation of the same sub result, you could use a bottom-up, iterative solution, building a row of Pascal's triangle , and then the next one from it, ...etc:为避免重复重新计算相同的子结果,您可以使用自下而上的迭代解决方案,构建一行Pascal's triangle ,然后从中构建下一个,...等:

def choose(n, k):
    lst = [1] * (n+1)
    for j in range(1, n):
        for i in range(j, 0, -1):
            lst[i] += lst[i-1]
    return lst[k]

print(choose(1000, 800))

661715556065930365627163346132458831897321703017638669364788134708891795956726411057801285583913163781806953211915554723373931451847059830252175887712457307547649354135460619296383882957897161889636280577155889117185 661715556065930365627163346132458831897321703017638669364788134708891795956726411057801285583913163781806953211915554723373931451847059830252175887712457307547649354135460619296383882957897161889636280577155889117185

This is just to show how to make the approach more efficient, but there are of course several more efficient ways to calculate C(n,k) .这只是为了展示如何使该方法更有效,但当然有几种更有效的方法来计算 C(n,k)

You can make the recursive approach perform a lot better by dividing through factors:您可以通过划分因子来使递归方法的性能更好

def choose(n, k):
    if k == 0:
        return 1
    return n * choose(n-1, k-1) // k

This uses the recurrence relation:这使用递归关系:

1

This approach will instantly compute 1000 C 800 without blowing the recursion stack.这种方法将立即计算 1000 C 800 而不会破坏递归堆栈。 But, the underlying problem is still there - it's just postponed to much larger numbers.但是,潜在的问题仍然存在——它只是被推迟到更大的数字上。 You may prefer to use one of the various closed-form solutions instead, for example:您可能更喜欢使用各种封闭形式的解决方案之一,例如:

from math import factorial

def choose(n, k):
    if n < k:
        n = k - n
    return factorial(n) // (factorial(k) * factorial(n-k))

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM