我真正的问题是,“为什么回溯不能加快我的搜索速度?” 但我不确定如果没有更多上下文这是否有意义......
这个问题实际上只是学术问题 - 代码“有效”并且我的程序找到了我期望的解决方案......但我想确保我理解这些术语。为了帮助说明问题,让我们使用一个需要搜索算法的特定示例 - n-Queens 问题。
n 皇后问题- 将 n 个皇后放置在 n×n 棋盘上,使得没有皇后可以攻击另一个。
一种解决方案
互联网上有很多示例代码可以通过搜索“N-queens backtracking”找到,维基百科关于回溯的文章甚至使用 N-Queens 来解释什么是回溯(http://en.wikipedia.org /wiki/回溯)。据我所知,这个想法是,给定一个无效的棋盘配置——假设两个可以互相攻击的皇后,该算法会忽略所有通过添加额外棋子而产生的棋盘配置。
我还实现了我的搜索的(非递归/非回溯)深度优先和广度优先版本。正如预期的那样,两种变体都测试了完全相同数量的状态。我希望使用回溯算法的递归深度优先应该测试更少的状态。但我没有看到。
Depth First
Found 92 solutions in 10.04 seconds
Tested 118969 nodes (1.2k nodes per second)
Largest Memory Set was 64 nodes
BackTracking
Found 92 solutions in 9.89 seconds
Tested 118969 nodes (1.2k nodes per second)
Largest Memory Set was 170 nodes
Breadth First
Found 92 solutions in 12.52 seconds
Tested 118969 nodes (0.95k nodes per second)
Largest Memory Set was 49415 nodes
我的实际实现是通用的,所以我没有利用板镜/旋转或其他任何聪明的东西。
我觉得我一定是误解了,但我没有看到回溯给我带来什么好处?
维基百科解释说,一旦发现给定状态无效,它的子树就会被跳过(修剪),但是合理地放置皇后(避免 a8 中的 Q1 和 a7 中的 Q2)似乎可以防止任何可以修剪的情况?
我的呼吸优先实施应该考虑回溯避免哪些板配置?