问题
我知道在我的功能中某处,我没有回复我想要的东西。
我正在返回递归调用,但似乎我没有“完全退出”
上下文
我正在对列表中的每个组合进行深度优先搜索。一旦达到达到某种状态的组合,我想回来。
我正在维持我的组合的“状态”,并且正在回溯我应该(我认为)。
我做错了什么?
class Combo:
def __init__(self, list):
self.staples = list
Combo有一个名为“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)
答案 0 :(得分:1)
if
循环中的第一个for
语句不会返回任何内容。 应该返回的内容取决于算法的逻辑:
#If exceeds target value, backtrack
if combo.findConflict(target):
staple.decrement()
combo.calcTotals()
combo.findDiff(target)
return SOMETHING
此外,最后3行不会被执行,在<{strong> return
语句之后 。
答案 1 :(得分:1)
如果我正确理解您的代码(这比平时更难,因为您没有显示您在combo
和staple
上调用的大部分方法),这应该是你想要什么:
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
最后return None
并非绝对必要,因为None
是默认返回值,如果您不返回任何其他内容。我只是认为最好明确一点。
我正在关注您的代码,在成功时返回combo
(并在失败时将其扩展为返回None
)。由于代码在适当的位置变异combo
,您也可以返回True
表示成功(在函数顶部的基本情况下)和False
表示失败(在底部该函数,在循环结束后)。递归逻辑将传递True
结果,并在False
结果后回溯。如果顶级调用者获得combo
返回值,则需要检查他们为实际解决方案传入的True
实例:
combo = Combo(something)
if IterateStaples(combo, target):
do_stuff(combo) # success!
答案 2 :(得分:0)
我能够通过在以下内容中加入辅助函数来传递我自己的测试用例:
这不是回溯吗?我用类似的方法实现了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