我正在尝试为骑士之旅编写代码:
骑士之旅是指骑士在棋盘上的一系列动作,以使骑士只能在每个广场上造访一次。
我一直在尝试更改其他人的代码,但是回溯似乎无法正常进行- 它从未找到解决方案。当骑士从0,0开始时,它工作得很好,但是如果它从2D网格上的任何其他位置开始,则该程序将永远继续下去。
此代码中的错误在哪里?
#include <iostream> #include <ctime> using namespace std; const int N = 8; int map[N][N]; /* A utility function to check if i,j are valid indexes for N*N chessboard */ bool isSafe(int x, int y) { return x >= 0 && x < N && y >= 0 && y < N && map[x][y] == -1; } /* A utility function to print solution matrix sol[N][N] */ void printSolution() { for (int x = 0; x < N; x++) { for (int y = 0; y < N; y++) cout << map[x][y]; cout << endl; } } /* A recursive utility function to solve Knight Tour problem */ bool knightsTourRecursive(int x, int y, int movei, int xMove[N], int yMove[N]) { int nextX, nextY; if (movei == N*N) return true; /* Try all next moves from the current coordinate x, y */ for (int k = 0; k < 8; k++) { nextX = x + xMove[k]; nextY = y + yMove[k]; if (isSafe(nextX, nextY)) { map[nextX][nextY] = movei; if (knightsTourRecursive(nextX, nextY, movei+1, xMove, yMove)) // recursion return true; else map[nextX][nextY] = -1; // backtracking } } return false; } bool knightsTour() { /* Initialization of solution matrix */ for (int x = 0; x < N; x++) for (int y = 0; y < N; y++) map[x][y] = -1; /* xMove[] and yMove[] define next move of Knight. xMove[] is for next value of x coordinate yMove[] is for next value of y coordinate */ int xMove[8] = { 2, 1, -1, -2, -2, -1, 1, 2 }; int yMove[8] = { 1, 2, 2, 1, -1, -2, -2, -1 }; int initX = rand() % N; int initY = rand() % N; cout << "Starting at " << initX << " " << initY << endl; // Since the Knight is initially at the first block map[initX][initY] = 0; /* explore all tours using solveKTUtil() */ if(!knightsTourRecursive(initX, initY, 1, xMove, yMove) ) { cout << "Solution does not exist" << endl; return false; } else printSolution(); return true; } int main() { srand( (unsigned) time(0)); knightsTour(); cin.get(); return 0; }
这个程序似乎是绝对正确的,我看不到这段代码中的错误。
但是,骑士之旅是一个非常复杂的算法。实际上,该程序最多需要通过板检查64!= 1 * 2 * 3 * … * 64种不同的方式。这是89个零的数字!
在许多情况下,回溯将在早期分支处停止,但某些分支将永远上升。
如果从0,0开始的巡回执行得如此之快,则它可能是纯粹的偶然机会,或者是巧妙地初始化了数组xMove和yMove,从而很快找到了(0,0)的解决方案。
因此,问题不在于您的程序,而在于算法。我建议您对此主题进行一些研究。骑士之旅有很多算法,可以在更合理的时间内为您提供解决方案。