有最后关于骑士之旅一个有趣的话题,然后我们将继续到深度优先搜索的通用版本。主题是性能。特别是,knightTour
对于你选择下一个要访问的顶点的方法非常敏感。例如,在一个5乘5的板上,你可以在快速计算机上处理路径花费大约1.5秒。但是如果你尝试一个
Figure 12-13
我们已经看到,高度 N 的二叉树中的节点数量是
幸运的是有一种方法来加速八乘八的情况,使其在一秒钟内运行完成。在下面的列表中,我们将展示加速 knightTour
的代码。这个函数(见Listing 4),被称为 orderbyAvail
将被用来代替上面代码中对 u.getConnections
的调用。orderByAvail
函数中的关键是第 10 行。此行确保我们选择具有最少可用移动的下一个顶点。你可能认为这具有相反效果; 为什么不选择具有最多可用移动的节点?你可以通过运行该程序并在排序后插入行resList.reverse()
来尝试该方法。
使用具有最多可用移动的顶点作为路径上的下一个顶点的问题是,它倾向于让骑士在游览中早访问中间的方格。当这种情况发生时,骑士很容易陷入板的一侧,在那里它不能到达在板的另一侧的未访问的方格。另一方面,访问具有最少可用移动的方块首先推动骑士访问围绕板的边缘的方块。这确保了骑士能够尽早地访问难以到达的角落,并且只有在必要时才使用中间的方块跳过棋盘。利用这种知识加速算法被称为启发式。人类每天都使用启发式来帮助做出决策,启发式搜索通常用于人工智能领域。这个特定的启发式称为 Warnsdorff
算法,由 H. C. Warnsdorff
命名,他在 1823 年发表了他的算法。
def orderByAvail(n):
resList = []
for v in n.getConnections():
if v.getColor() == 'white':
c = 0
for w in v.getConnections():
if w.getColor() == 'white':
c = c + 1
resList.append((c,v))
resList.sort(key=lambda x: x[0])
return [y[1] for y in resList]
Next Section - 7.15. General Depth First Search