Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/289.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 间隔计划:如何跟踪到目前为止尝试的计划?_Python_Recursion_Dynamic Programming - Fatal编程技术网

Python 间隔计划:如何跟踪到目前为止尝试的计划?

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:

我花了无数个小时试图解决这个问题,但没有成功。我试图解决的问题是找到能提供最大价值的路径(即任务时间表)。看

在下图中,您可以看到任务1的值为5(红色数字),开始于
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,以便于添加到列表中)