避免针对DP的尾部递归python

避免针对DP的尾部递归python,python,recursion,dynamic-programming,tail-recursion,Python,Recursion,Dynamic Programming,Tail Recursion,我用Python编写了以下递归函数,用于在DP算法中计算加权间隔调度问题的解决方案,其中间隔是“排序的_操作”。我正在阅读Kleinberg和Tardos的《算法设计》一书,OPT和p_列表已经计算过了。它似乎适用于相对较小的实例,但一旦问题的规模增大,我就会超过“最大递归深度”,并得到一个错误。由于增加sys.setrecursionlimit会使内核崩溃,我想知道是否还有其他方法来编写此函数 solution_set = [] def compute_solution(j): if

我用Python编写了以下递归函数,用于在DP算法中计算加权间隔调度问题的解决方案,其中间隔是“排序的_操作”。我正在阅读Kleinberg和Tardos的《算法设计》一书,OPT和p_列表已经计算过了。它似乎适用于相对较小的实例,但一旦问题的规模增大,我就会超过“最大递归深度”,并得到一个错误。由于增加sys.setrecursionlimit会使内核崩溃,我想知道是否还有其他方法来编写此函数

solution_set = []
def compute_solution(j):
    if j<=0:
       pass
    else:
        if sorted_operations[j]['weight'] + OPT[p_list[j]] > OPT[j - 1]:
            solution_set.append(sorted_operations[j])
            print(j)
            compute_solution(p_list[j])
        else:
            compute_solution(j - 1)

compute_solution(len(sorted_operations) - 1)
solution\u set=[]
def计算溶液(j):
如果j OPT[j-1]:
解决方案\u集.append(排序的\u操作[j])
印刷品(j)
计算解(p_列表[j])
其他:
计算解(j-1)
计算解决方案(len(排序运算)-1)

如果不了解您的代码,我无法提供详细的解决方案。然而,你的算法的一部分确实在我的脑海中浮现出来:
compute\u solution(j-1)
。由于
j
是一个整数,因此使用
j-1
再次调用算法比方法调用更适合循环,特别是因为在Python中这些调用往往有点昂贵。因此,我将修改您的算法如下:

solution_set = []
def compute_solution(j):
    while (j > 0):
        if sorted_operations[j]['weight'] + OPT[p_list[j]] > OPT[j - 1]:
            solution_set.append(sorted_operations[j])
            print(j)
            compute_solution(p_list[j])
            return
        else:
            j = j - 1

compute_solution(len(sorted_operations) - 1)

根据
else
语句的运行频率,这可能是一个主要的好处。

代码有点混乱,但您可以使用迭代而不是递归。如果看不到
p\u列表
排序的\u操作
(或至少是其中的一个子集)和
OPT
,我真的无法提供建议或解决方案。还有,你说“你的问题越来越严重”是什么意思?它从何而来,又从何而来?如果
len(已排序的\u操作)
~1000,那么我会说您有问题,但是如果
len(已排序的\u操作)
~1000000可能没有。谢谢@Woody。我尝试了一下,它似乎适用于更大的实例(例如10000次间隔)。但是,不太清楚为什么在if语句中使用@Michele如果不使用
break
则会陷入无限循环,因为
j
的值仅在
else
中更新,而且不清楚
if
是否会在后续调用中得到相同的结果。请注意,如果您想将
return
语句用作基本情况,则该语句同样有效,但我不确定在您的问题代码之后是否存在其他代码