递归回溯-python。不返回值

递归回溯-python。不返回值,python,recursion,backtracking,recursive-backtracking,Python,Recursion,Backtracking,Recursive Backtracking,问题 我意识到在我的功能中,我没有返回我应该返回的东西 我正在返回递归调用,但似乎我并没有返回“全部退出” 上下文 我正在对列表中的每个组合进行深度优先搜索。一旦我达到一个组合,达到一个条件,我想返回 我保持着我组合的“状态”,并在回溯我应该在的位置(我认为) 我做错了什么 class Combo: def __init__(self, list): self.staples = list Combo有一个名为“staples”的属性,由一系列staples类组成。我想迭

问题

我意识到在我的功能中,我没有返回我应该返回的东西

我正在返回递归调用,但似乎我并没有返回“全部退出”

上下文

我正在对列表中的每个组合进行深度优先搜索。一旦我达到一个组合,达到一个条件,我想返回

我保持着我组合的“状态”,并在回溯我应该在的位置(我认为)

我做错了什么

class Combo:
    def __init__(self, list):
       self.staples = list
Combo有一个名为“staples”的属性,由一系列staples类组成。我想迭代决策树中的订书钉列表,以找到一个最佳数量

在这种情况下,最佳数量在列表中每个装订实例的数量上求和,并作为Combo实例上的属性存储/重新计算

def IterateStaples(combo, target):        
  #Exit condition for combo dictionary
  if all(combo.diff[macro] < 2 for macro in combo.diff):    
    return combo;                            

  #iterate through all items in list
  for staple in combo.staples:                                  

    #Increment and calc conditions
    staple.increment()         
    combo.calcTotals()      
    combo.findDiff(target)

    #If exceeds target value, backtrack
    if combo.findConflict(target):                
      staple.decrement()
      combo.calcTotals()                
      combo.findDiff(target)              

    #Redundant exit condition to try and return
    elif all(combo.diff[macro] < 2 for macro in combo.diff):                                  
      return combo                

    #Recursive call
    else:        
      return IterateStaples(combo, target)
      staple.decrement()
      combo.calcTotals()
      combo.findDiff(target)
def iteratestales(组合,目标):
#组合字典的退出条件
如果全部(combo.diff[macro]<2表示combo.diff中的宏):
返回组合;
#遍历列表中的所有项
对于combo.staples中的装订:
#增量和计算条件
stype.increment()
combo.calcTotals()
combo.findDiff(目标)
#如果超过目标值,则返回
如果combo.findConflict(目标):
主食减量
combo.calcTotals()
combo.findDiff(目标)
#要尝试并返回的冗余退出条件
elif all(combo.diff[macro]<2表示combo.diff中的宏):
返回组合
#递归调用
其他:
返回迭代示例(组合,目标)
主食减量
combo.calcTotals()
combo.findDiff(目标)

for循环中的
if
语句没有返回任何内容。它应该返回什么取决于算法的逻辑:

#If exceeds target value, backtrack
if combo.findConflict(target):                
   staple.decrement()
   combo.calcTotals()                
   combo.findDiff(target)
   return SOMETHING

此外,最后3行永远不会执行,它们在
return
语句之后

如果
for
循环中的
语句没有返回任何内容,则第一行
。它应该返回什么取决于算法的逻辑:

#If exceeds target value, backtrack
if combo.findConflict(target):                
   staple.decrement()
   combo.calcTotals()                
   combo.findDiff(target)
   return SOMETHING

另外,最后3行永远不会被执行,它们在
return
语句之后

我通过在以下代码中加入一个helper函数,通过了我自己的测试用例:

这不是回溯吗?我用类似的方法实现了N-queens

def IterateStaples(combo, target):        
  #iterate through all items in list
  bestCombo = []
  def helper(combo):
    for staple in combo.staples:                                      
      #Increment and calc conditions
      staple.increment()         
      combo.calcTotals()      
      combo.findDiff(target)    

      #If exceeds target value, backtrack
      if combo.findConflict(target):                      
        staple.decrement()
        combo.calcTotals()                
        combo.findDiff(target)                                        

      #Redundant exit condition to try and return
      elif all(combo.diff[macro] < 2 for macro in combo.diff):                                          
        bestCombo.append(deepcopy(combo))        
        return                

      #Recursive call
      else:        
        helper(combo)
        staple.decrement()
        combo.calcTotals()
        combo.findDiff(target)

  helper(combo)  

  return bestCombo
def iteratestales(组合,目标):
#遍历列表中的所有项
最佳组合=[]
def辅助程序(组合):
对于combo.staples中的装订:
#增量和计算条件
stype.increment()
combo.calcTotals()
combo.findDiff(目标)
#如果超过目标值,则返回
如果combo.findConflict(目标):
主食减量
combo.calcTotals()
combo.findDiff(目标)
#要尝试并返回的冗余退出条件
elif all(combo.diff[macro]<2表示combo.diff中的宏):
最佳组合追加(deepcopy(组合))
返回
#递归调用
其他:
助手(组合)
主食减量
combo.calcTotals()
combo.findDiff(目标)
助手(组合)
返回最佳组合

通过将助手函数合并到以下内容中,我能够通过自己的测试用例:

这不是回溯吗?我用类似的方法实现了N-queens

def IterateStaples(combo, target):        
  #iterate through all items in list
  bestCombo = []
  def helper(combo):
    for staple in combo.staples:                                      
      #Increment and calc conditions
      staple.increment()         
      combo.calcTotals()      
      combo.findDiff(target)    

      #If exceeds target value, backtrack
      if combo.findConflict(target):                      
        staple.decrement()
        combo.calcTotals()                
        combo.findDiff(target)                                        

      #Redundant exit condition to try and return
      elif all(combo.diff[macro] < 2 for macro in combo.diff):                                          
        bestCombo.append(deepcopy(combo))        
        return                

      #Recursive call
      else:        
        helper(combo)
        staple.decrement()
        combo.calcTotals()
        combo.findDiff(target)

  helper(combo)  

  return bestCombo
def iteratestales(组合,目标):
#遍历列表中的所有项
最佳组合=[]
def辅助程序(组合):
对于combo.staples中的装订:
#增量和计算条件
stype.increment()
combo.calcTotals()
combo.findDiff(目标)
#如果超过目标值,则返回
如果combo.findConflict(目标):
主食减量
combo.calcTotals()
combo.findDiff(目标)
#要尝试并返回的冗余退出条件
elif all(combo.diff[macro]<2表示combo.diff中的宏):
最佳组合追加(deepcopy(组合))
返回
#递归调用
其他:
助手(组合)
主食减量
combo.calcTotals()
combo.findDiff(目标)
助手(组合)
返回最佳组合

如果我正确理解了您的代码(这比平常更难,因为您没有显示您调用的大多数方法是什么
combo
stalk
),这应该是您想要的:

def IterateStaples(combo, target):        
    # base case
    if all(combo.diff[macro] < 2 for macro in combo.diff): # iterate on combo.diff.values()?
        return combo   # returning combo indicates success!

    for staple in combo.staples:
        staple.increment()                 # update state   
        combo.calcTotals()      
        combo.findDiff(target)

        if not combo.findConflict(target):  # skip recursing on invalid states
            result = IterateStaples(combo, target)    # recursive case
            if result is not None:      # if the recursion was successful, return the result
                return result

        staple.decrement()  # otherwise, undo the change to the state (backtrack)
        combo.calcTotals()     # these two lines might not be necessary when backtracking
        combo.findDiff(target) # since other branches will call them after staple.increment()

    return None # if we got to the end of the loop, explicitly return None to signal failure

如果我正确理解了您的代码(这比平常更难,因为您没有显示您调用的大多数方法
combo
stuble
是什么),这应该是您想要的:

def IterateStaples(combo, target):        
    # base case
    if all(combo.diff[macro] < 2 for macro in combo.diff): # iterate on combo.diff.values()?
        return combo   # returning combo indicates success!

    for staple in combo.staples:
        staple.increment()                 # update state   
        combo.calcTotals()      
        combo.findDiff(target)

        if not combo.findConflict(target):  # skip recursing on invalid states
            result = IterateStaples(combo, target)    # recursive case
            if result is not None:      # if the recursion was successful, return the result
                return result

        staple.decrement()  # otherwise, undo the change to the state (backtrack)
        combo.calcTotals()     # these two lines might not be necessary when backtracking
        combo.findDiff(target) # since other branches will call them after staple.increment()

    return None # if we got to the end of the loop, explicitly return None to signal failure

因为我正在迭代一个集合,而决策树的这个分支对我来说没有用处,所以我需要返回什么吗?在最后4行中,我最初有一个函数调用,而不是返回。不过,我现在正在尝试你的建议。“决策树的这个分支对我没有用处”不适用于递归算法。如果迭代依赖于嵌套调用的结果,则该嵌套调用必须返回相关结果。@Amit您的答案会使for循环无效,因为它总是在第一次迭代时退出函数。因为我正在迭代集合,而决策树的这一分支对我没有用处,我需要返回什么吗?我最初有一个函数调用,而不是上一次的返回