[英]How to correctly implement memoization?
I have been spending way too much time on a programming challenge:我在编程挑战上花费了太多时间:
Given a budget and a set of prices, compute all unique combinations on how to spend the entire budget.给定一个预算和一组价格,计算如何花费整个预算的所有独特组合。
budget = 100
prices = [25, 50]
[[25, 25, 25, 25], [25, 25, 50], [25, 50, 25], [50, 25, 25], [50, 50]]
I have implemented a brute force solution in Python that works correctly:我在 Python 中实施了一个正常工作的蛮力解决方案:
def spend_the_budget(budget: int, prices: list) -> list:
if budget == 0:
return [[]]
if budget < 0:
return None
combinations = []
for price in prices:
remainder = budget - price
remainder_combinations = spend_the_budget(remainder, prices)
if remainder_combinations is not None:
for remainder_combination in remainder_combinations:
remainder_combination += [price]
combinations.append(remainder_combination)
return combinations
However, this has obviously exponential time complexity and therefore doesn't scale in an acceptable fashion.然而,这显然具有指数时间复杂度,因此不能以可接受的方式扩展。 Therefore I'd like to add memoization but can't seem to get it to work:
因此我想添加记忆,但似乎无法让它工作:
def spend_the_budget_memoized(budget: int, prices: list, memo: dict = {}) -> list:
if budget in memo:
return memo[budget]
if budget == 0:
return [[]]
if budget < 0:
return None
combinations = []
for price in prices:
remainder = budget - price
remainder_combinations = spend_the_budget_memoized(remainder, prices, memo)
if remainder_combinations is not None:
for remainder_combination in remainder_combinations:
remainder_combination += [price]
combinations.append(remainder_combination)
memo[budget] = combinations
return combinations
Weirdly enough however, this yields an incorrect result and I just can't wrap around my head as to what I did wrong here:然而,奇怪的是,这会产生一个不正确的结果,我无法理解我在这里做错了什么:
[[25, 25, 25, 50, 25, 25, 50], [50, 25, 25, 50], [25, 25, 25, 50, 25, 25, 50], [25, 25, 25, 50, 25, 25, 50], [50, 25, 25, 50]]
for remainder_combination in remainder_combinations:
remainder_combination += [price]
combinations.append(remainder_combination)
When you iterate over remainder_combinations
you are iterating over the same copy which is stored in memo
.当您迭代
remainder_combinations
组合时,您正在迭代存储在memo
中的同一个副本。 Use list.copy() instead,使用 list.copy() 代替,
for remainder_combination in remainder_combinations:
temp = remainder_combination.copy()
temp += [price]
combinations.append(temp)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.