我正在尝试为the Knight’s Tour编写代码:
A knight’s tour is a sequence of moves of a knight on a chessboard such that the knight visits every square exactly once.
我一直试图改变其他人的代码,但回溯似乎无法正常工作 – 它永远找不到解决方案.当骑士从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)的解.
所以问题不是你的程序,而是算法.我建议你对这个话题做一些研究.骑士之旅有很多算法,可以在更合理的时间内为您提供解决方案.