在大多数分支组合搜索算法中,我已经看到,深度优先搜索中的每个递归调用都是使用当前解决方案状态的副本进行的(以确保分支可以始终恢复到给定的解决方案状态,如果一个分支结果证明是没有结果的。)
例如,采用Peter Norvig的数独求解器搜索功能:
def search(values):
"Using depth-first search and propagation, try all possible values."
if values is False:
return False ## Failed earlier
if all(len(values[s]) == 1 for s in squares):
return values ## Solved!
## Chose the unfilled square s with the fewest possibilities
n, s = min((len(values[s]), s) for s in squares if len(values[s]) > 1)
return some(search(assign(values.copy(), s, d))
for d in values[s])
问题:是否有一种标准方法可以避免每次进行递归调用时都必须执行整个解决方案/约束空间的副本?具体来说,是否有可能在每次递归调用时都不会复制values
来实现Norvig的数独求解器?
我尝试了什么?
1)在全局解决方案对象上迭代实现搜索。仔细管理传播约束的构造性添加和破坏性删除到全局解决方案对象,以便先前的分支决策可以恢复。
2)使用持久树结构来表示我的解决方案状态。我还没有能够实现这一点,我甚至不确定它是否有意义。