避免针对DP的尾部递归python
我用Python编写了以下递归函数,用于在DP算法中计算加权间隔调度问题的解决方案,其中间隔是“排序的_操作”。我正在阅读Kleinberg和Tardos的《算法设计》一书,OPT和p_列表已经计算过了。它似乎适用于相对较小的实例,但一旦问题的规模增大,我就会超过“最大递归深度”,并得到一个错误。由于增加sys.setrecursionlimit会使内核崩溃,我想知道是否还有其他方法来编写此函数避免针对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
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
语句用作基本情况,则该语句同样有效,但我不确定在您的问题代码之后是否存在其他代码