使用memoization的递归算法

时间:2013-05-10 09:16:56

标签: python recursion memoization

我的问题如下: 我有一份任务列表,每个任务都花费一定的时间并给予特定数量的点数,并给出执行它们的时间'k':

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

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

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

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

这是我到目前为止所获得的,我需要帮助实现上面所需的内容,我的意思是字典用法(目前只是在那里并且一直是空的),以及我的choose_mem函数输入是{{ 1}}它应该是i,j,missions,d,其中mem = d,k是可供选择的任务数量。

如果有人可以帮我调整我的代码,我们将非常感激。

choose_mem(missions, time, mem, k)

1 个答案:

答案 0 :(得分:4)

这有点模糊,但你的问题大致转化为一个非常着名的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

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