python - 用于查找组合而不达到python内置限制的递归函数
问题描述
我已经组合了一个函数,用于使用递归查找组合,而不会达到 python 中的内置限制。例如,您可以计算:choose(1000, 500)。这是它现在的样子:
def choose(n, k):
if not k:
return 1 .
elif n < k:
return 0
else:
return ((n + 1 - k) / k) * choose(n, k - 1)
它完全按照我想要的方式工作。如果 k 为 0,则返回 1,如果 n 小于 k,则返回 0(这是根据我在 wikipedia 上找到的数学定义)。但是,问题是我不太了解最后一行(我在浏览网页时发现的)。在我目前使用的最后一行之前,这是我在函数中的最后一行:
return choose(n-1,k-1) + choose(n-1, k)
我也在维基百科上找到了它(尽管我认为我也不是 100% 理解这个)。但是由于python中的内置限制,它总是会导致错误,而我正在使用的新行不会导致这样的错误。我知道新行在程序中的工作效率更高,因为例如我们不会将其拆分为两个子问题。
再说一遍..我要问的是,是否有任何善良的灵魂可以(以一种可以理解的方式)解释这行代码在函数中是如何工作的:
return ((n + 1 - k) / k) * choose(n, k - 1)
解决方案
剧透:底线是你应该使用封闭的形式n! / (k! (n - k)!)
。
在许多其他语言中,解决方案是使您的函数tail-recursive,尽管 Python 不支持这种优化。因此,实现递归解决方案根本不是最佳选择。
您可以使用 增加最大递归深度sys.setrecursionlimit
,但这不是最优的。
一种改进是通过迭代计算n-choose-k。
def choose(n, k):
if n < k:
return 0
ans = 1
while k > 0:
ans *= (n + 1 - k) / k
k -= 1
return ans
虽然,由于浮点运算,上述内容会累积错误。因此,最好的方法是使用n-choose-k的封闭形式。
from math import factorial
def choose(n, k):
return factorial(n) / (factorial(k) * factorial(n - k))
推荐阅读
- javascript - 正则表达式匹配一个数字但不在另一个数字内
- spring-cloud-dataflow - spring cloud dataflow重启后无法再次部署之前的flow
- javascript - Laravel 中的 Firebase 资源
- c++ - 带有 chrono::sleep_until 的奇怪日志记录时间戳
- node.js - Google 登录 React 和 Node .js
- javascript - 从与 webpack 捆绑的包中导入时,VScode 智能感知不起作用
- python - 检查 pandas 列是否包含另一个数据框中的文本并替换值
- xquery - xquery 处理空间和子节点
- c# - 将 Eigen::VectorXd 和 Eigen::Vector2d 从 C++ 传递到 Unity C#
- java - 有没有一种在 Java 中重新排列链表的方法?