Python 间隔计划:如何跟踪到目前为止尝试的计划?
我花了无数个小时试图解决这个问题,但没有成功。我试图解决的问题是找到能提供最大价值的路径(即任务时间表)。看 在下图中,您可以看到任务1的值为5(红色数字),开始于Python 间隔计划:如何跟踪到目前为止尝试的计划?,python,recursion,dynamic-programming,Python,Recursion,Dynamic Programming,我花了无数个小时试图解决这个问题,但没有成功。我试图解决的问题是找到能提供最大价值的路径(即任务时间表)。看 在下图中,您可以看到任务1的值为5(红色数字),开始于t=1,结束于t=4。任务2的值为1,开始于t=3,结束于t=5,以此类推 您不能执行任何重叠的任务。也就是说,如果我选择做任务1,我不能做任务2、3或5,但我可以做4,因为它是在任务1完成后直接开始的 因此,最好的可能结果是执行任务1、任务4,然后执行任务8。那值13分 我可以用下面的代码计算最大值: class Tasks:
t=1
,结束于t=4
。任务2的值为1,开始于t=3
,结束于t=5
,以此类推
您不能执行任何重叠的任务。也就是说,如果我选择做任务1,我不能做任务2、3或5,但我可以做4,因为它是在任务1完成后直接开始的
因此,最好的可能结果是执行任务1、任务4,然后执行任务8。那值13分
我可以用下面的代码计算最大值:
class Tasks:
def __init__(self, task_id, earnings, start_time, end_time):
self.task_id = task_id
self.earnings = earnings
self.start_time = start_time
self.end_time = end_time
self.duration = (end_time - start_time)
def value(n):
n_value = task_list[n-1].earnings
return n_value
def prev(n):
n_start = task_list[n-1].start_time
n_prev = 0
# cycles through list of tasks
for i, task in enumerate(task_list):
# if n_prev has been changed from its initial value of 0
if n_prev > 0:
# finds the latest task endtime that's less than or equal to the start of n
if n_start >= task.end_time > task_list[n_prev-1].end_time:
n_prev = task.task_id
else:
# else, n_prev is 0 and assigns it to the first task that ends before n starts
if n_start >= task.end_time:
n_prev = task.task_id
return n_prev
def get_max(n):
if n == 0:
return 0
# the earnings for doing the task
do_task = value(n) + get_max(prev(n))
# the earnings for not doing the task
dont_do_task = get_max(n-1)
# if doing the task earns more than not doing the task, return do_task
if do_task > dont_do_task:
path.append(n)
return do_task
# otherwise, return the value for not doing the task
else:
return dont_do_task
if __name__ == '__main__':
task_list = [
Tasks(1, 5, 1, 4),
Tasks(2, 1, 3, 5),
Tasks(3, 8, 0, 6),
Tasks(4, 4, 4, 7),
Tasks(5, 6, 3, 8),
Tasks(6, 3, 5, 9),
Tasks(7, 2, 6, 10),
Tasks(8, 4, 8, 11)
]
path = []
get_max(3)
问题是我不知道如何跟踪路径(或时间表)。如果我调用get_max(8)
,我希望维护一个包含1、4和8的列表,而不仅仅是它们组合的值。我不知道如何递归地使用这个函数,同时仍然跟踪已经探索过的路径
(旁注:get_max(0)=0
下面是一个示例的伪代码:get_max(3)
在完成之前进行递归调用:
get_max(2)
do_task = 1 + 0
dont_task = get_max(1)
get_max(1)
**do_task = 5 + 0**
dont_do_task = get_max(0)
在完成之前进行递归调用:
get_max(2)
do_task = 1 + 0
dont_task = get_max(1)
get_max(1)
**do_task = 5 + 0**
dont_do_task = get_max(0)
比较5和0并返回5,因此现在:
get_max(2)
do_task = 1 + get_max(0)
**dont_do_task = 5**
get_max(3)
**do_task = 8 + get_max(0)**
dont_do_task = 5
比较1和5并返回5,因此现在:
get_max(2)
do_task = 1 + get_max(0)
**dont_do_task = 5**
get_max(3)
**do_task = 8 + get_max(0)**
dont_do_task = 5
与8和5相比,8更大
现在,我知道我想做任务3。所以我想在我将要采用的路径列表中添加3条。然而,如果我添加了如下内容
if doing path:
path_list.append(n)
然后,当我在递归底部的get_max(1)中选择do_task时,它也会在from的路径列表中添加1,这是我不想要的。有没有办法确保我只是将相关路径添加到列表中
编辑
值得一提的是,我确实提出了一个解决方法,但它不是很优雅,它取决于按顺序调用get_max(n)。(我还从集合中导入了defaultdict,以便于添加到列表中)