【问题标题】:How to correctly implement memoization?如何正确实现memoization?
【发布时间】:2021-03-31 12:59:24
【问题描述】:

我在编程挑战上花费了太多时间:

给定预算和一组价格,计算所有独特组合如何花费整个预算。

示例

输入

budget = 100
prices = [25, 50]

输出

[[25, 25, 25, 25], [25, 25, 50], [25, 50, 25], [50, 25, 25], [50, 50]]

我已经在 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

但是,这显然具有指数时间复杂度,因此无法以可接受的方式扩展。因此我想添加 memoization 但似乎无法让它工作:

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

然而,奇怪的是,这会产生一个不正确的结果,我无法理解我在这里做错了什么:

输出

[[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]]

【问题讨论】:

  • 您正在(通过 +=)附加到记忆值。这将更新之前计算的结果。

标签: python algorithm memoization


【解决方案1】:
for remainder_combination in remainder_combinations:
                remainder_combination += [price]
                combinations.append(remainder_combination)

当您迭代 remainder_combinations 时,您正在迭代存储在 memo 中的同一个副本。请改用 list.copy(),

for remainder_combination in remainder_combinations:
                temp = remainder_combination.copy()
                temp += [price]
                combinations.append(temp)

【讨论】:

    猜你喜欢
    • 2018-06-12
    • 1970-01-01
    • 2019-04-16
    • 2015-02-27
    • 2013-07-22
    • 2021-08-17
    • 2011-07-31
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多