【问题标题】:Recursive algorithm using memoization使用记忆的递归算法
【发布时间】:2013-05-10 09:16:56
【问题描述】:

我的问题如下: 我有一个任务列表,每个任务需要特定的时间并授予特定数量的积分,以及执行它们的时间“k”:

例如:missions = [(14,3),(54,5),(5,4)]time = 15

在这个例子中,我有 3 个任务,第一个任务给我 14 分,耗时 3 分钟。 我总共有 15 分钟。 每个任务都是一个元组,第一个值是该任务的点数,第二个值是执行该任务所需的分钟数。

我必须使用记忆递归地找到在给定任务列表和给定时间下我能够获得的最大点数。

我正在尝试实现一个名为 choose(missions,time) 的函数,该函数将递归操作并使用函数 choose_mem(missions,time,mem,k) 来实现我的目标。 函数 choose_mem 应该得到 'k' ,这是可供选择的任务数,mem 是一个空字典,mem 将包含之前已经解决的所有问题。

这是我到目前为止所得到的,我需要帮助来实现上面的要求,我的意思是字典的使用(目前就在那里并且一直是空的),而且我的 choose_mem 函数输入是@987654323 @ 应该是 choose_mem(missions, time, mem, k) 其中 mem = d 和 k 是可供选择的任务数。

如果有人可以帮助我调整我的代码,将不胜感激。

mem = {}

def choose(missions, time):
    j = time
    result = []
    for i in range(len(missions), 0, -1):
        if choose_mem(missions, j, mem, i) != choose_mem(missions, j, mem, i-1):
            j -= missions[i - 1][1]
    return choose_mem(missions, time, mem, len(missions)) 

def choose_mem(missions, time, mem, k): 
    if k == 0: return 0
    points, a = missions[k - 1]
    if a > time:
        return choose_mem(missions, time, mem, k-1) 
    else:
        return max(choose_mem(missions, time, mem, k-1),
                   choose_mem(missions, time-a, mem, k-1) + points)

【问题讨论】:

  • 只有我一个人,还是你从来不更新你的字典?
  • 你是对的,如果你注意到的话,我实际上是在代码上方写的。这是我在介绍我的代码时需要帮助的事情之一。
  • 编辑了我的答案,希望对您有所帮助。
  • 它有帮助。我稍微修改了我的代码,所以我认为现在更容易理解了。我所有的东西都准备好了。我现在唯一要做的就是检查'mem' = 我的字典是否包含我正在寻找的答案。我真的很挣扎,我找不到一种方法将字典添加到我的代码中,这是有意义的。你能帮我最后的忙吗,这样我才能完成这个程序?
  • 用你可能觉得有用的链接更新我的答案。

标签: python recursion memoization


【解决方案1】:

这有点含糊,但您的问题大致翻译为一个非常著名的 NP 完全问题,即背包问题。

你可以在维基百科上阅读更多关于它的信息,如果你用时间代替重量,你就有问题了。

动态编程是解决该问题的常用方法,您可以在此处看到: http://en.wikipedia.org/wiki/Knapsack_problem#Dynamic_programming

Memoization 或多或少等同于动态编程,就实际问题而言,所以不要让花哨的名字欺骗了你。

基本概念是您使用额外的数据结构来存储您已经解决的部分问题。由于您正在实施的解决方案是递归的,因此许多子问题会重叠,并且记忆化允许您只计算每个子问题一次。

因此,困难的部分是让您考虑您的问题,您需要在字典中存储什么,以便当您使用已经计算的值调用 choose_mem 时,您只需从字典中检索它们,而不是进行另一个递归调用。

如果您想检查通用 0-1 背包问题的实现(您的情况,因为您不能部分添加项目),那么在我看来这是一个很好的资源:

https://sites.google.com/site/mikescoderama/Home/0-1-knapsack-problem-in-p

解释得很好,代码也足够可读。如果您了解使用矩阵来存储成本,那么您的问题就会为您解决。

【讨论】:

  • 哇,是的,我刚刚检查了维基百科上的背包问题,它似乎与我的几乎完全一样(除了它的重量而不是你指出的时间)。感谢您的帮助,我一定会尝试使用那里的信息来解决我的问题。
  • 如果您可以查看我刚刚编辑的新代码,将不胜感激。该代码现在实际上可以工作,但我被要求提供特定类型的函数,这意味着 choose_mem 应该如下所示:choose_mem(missions, time, mem, k) 其中 mem 是“d”字典,k 是任务数离开。
猜你喜欢
  • 2018-04-19
  • 1970-01-01
  • 2011-02-04
  • 2010-10-03
  • 1970-01-01
  • 1970-01-01
  • 2014-05-03
  • 1970-01-01
  • 2012-11-12
相关资源
最近更新 更多