您的算法似乎运行良好,可以为较小的问题实例(例如5x5或7x7电路板)提供正确的结果。对于强力
/回溯方法来说,似乎8x8板太大了。
尽管如此,您仍然可以简化
findTour方法,使其更易于理解和调试:
public boolean findTour(int x, int y, int c) { solutionBoard[x][y] = c; if (c == size*size) { return true; } for (Point p : MOVES) { Point dst = new Point(x + p.x, y + p.y); if (canMove(dst) && findTour(dst.x, dst.y, c + 1)) { return true; }} solutionBoard[x][y] = -1; return false;}findTour(0, 0, 1)with的示例输出
size = 7(需要使所有代码适应可变大小!)
1 14 3 38 5 34 7 12 39 10 33 8 37 26 15 2 13 4 25 6 35 40 11 32 9 36 27 44 19 16 21 24 45 48 29 22 41 18 31 28 43 46 17 20 23 42 47 30 49
更好的方法是:使用Wikipedia文章中提到的其他算法之一,例如相当简单的Warnsdorff启发式算法:
“我们移动骑士,以便我们始终前进到骑士前进最少的位置。”
我们可以通过排序动作来实现这一目标…
public Point[] sortedPoints(final int x, final int y) { Point[] sorted = Arrays.copyOf(MOVES, MOVES.length); Arrays.sort(sorted, new Comparator<Point>() { public int compare(Point p1, Point p2) { return Integer.signum(nextMoves(p1) - nextMoves(p2)); }; private int nextMoves(Point p) { Point dst = new Point(x + p.x, y + p.y); if (canMove(dst)) { int s = 0; for (Point m : MOVES) { Point dst2 = new Point(dst.x + m.x, dst.y + m.y); if (canMove(dst2)) { s++; } } return s; } else { return 999; } } }); return sorted;}…,并将后继者循环更改为
for (Point p : sortedPoints(x, y))。结果:
size findTour calls without and with heuristic5x5 76497 25 7x7 8947880 498x8 ??? 6420x20 ??? 400
确实,对于我尝试过的所有尺寸,该
findTour方法都称为 精确
size^2时间,即它在第一次尝试时就找到了游览路线,而根本没有回溯。



