【发布时间】:2021-02-10 08:33:40
【问题描述】:
我正在练习动态编程的概念(递归不是我的强项)。我想知道如何改进我的代码,以避免堆栈溢出。
有什么帮助,谢谢!
def coinFlipping(n):
"""
For n amount of change, return the minimal amount of currency in coins.
Top-Down Approach (Memoization): Memo dictionary stores already solved
subproblems to reuse and avoid recomputing. It's essentially recursion
but optimized to avoid recomputing results.
"""
COINS = {
"penny": 0.01,
"nickel": 0.05,
"dime": 0.10,
"quarter": 0.25,
"dollar": 1.00
}
memo = {}
def __coinFlipping(n):
if n not in memo:
# Base case (if n is equal to 0.01, 0.05, 0.10, 0.25..)
if n in COINS.values():
memo[n] = 1
else:
results = []
coins = (coin for coin in COINS.values() if coin < n)
for coin in coins:
results.append(__coinFlipping(n - coin))
memo[n] = 1 + min(results)
else:
return memo[n]
__coinFlipping(n)
print(memo[n])
coinFlipping(10)
我得到以下错误:
File "/mnt/d/programs/algorithms/dynamicProgramming.py", line 45, in __coinFlipping
results.append(__coinFlipping(n - coin))
File "/mnt/d/programs/algorithms/dynamicProgramming.py", line 45, in __coinFlipping
results.append(__coinFlipping(n - coin))
File "/mnt/d/programs/algorithms/dynamicProgramming.py", line 45, in __coinFlipping
results.append(__coinFlipping(n - coin))
[Previous line repeated 993 more times]
File "/mnt/d/programs/algorithms/dynamicProgramming.py", line 44, in __coinFlipping
for coin in coins:
File "/mnt/d/programs/algorithms/dynamicProgramming.py", line 43, in <genexpr>
coins = (coin for coin in COINS.values() if coin < n)
RecursionError: maximum recursion depth exceeded in comparison
【问题讨论】:
-
嗯,这样的闭包是一种记忆方法(这回答了标题中的“问题”——确保标题与实际问题相关)。除了,修复 Too Much Recursion 问题。
-
也就是说,这里使用浮点值是有问题的,因为这些值的精度有限。将 0.05 视为 5、将 0.25 视为 25 等将是有益的。
-
写入浮点精度,这是false (!!!),例如:
0.01 + 0.01 + 0.10 == 0.12。可能还有其他逻辑错误,没看——需要调试细节和重点,尤其是在标题中。 -
__coinFlipping在缓存未命中时不返回任何内容。解决方法可能是删除else子句并始终返回memo[n],无论是否存在缓存命中或未命中。
标签: python recursion dynamic-programming memoization coin-change