国际象棋骑士之旅代码不起作用

时间:2018-08-03 17:28:34

标签: c++ recursion backtracking recursive-backtracking

我使用递归回溯的国际象棋骑士之旅代码不起作用。

#include <iostream>

using namespace std;
// goal: knight tour
#define N 8
void printArray(int board[N][N])
{
    for(int i = 0; i < N; i ++)
    {
        for(int j = 0; j < N; j ++)
        {
            cout << board[i][j] << " ";
        }
        cout << endl;
    }
}
void instArray(int board[N][N])
{
    for(int i = 0; i < N; i ++)
        for(int j = 0; j < N; j ++)
            board[i][j] = 0;
    board[0][0] = 1;
}
bool isValidMove(int posX, int posY, int moveX, int moveY, int board[N][N])
{
    int finalX = posX + moveX;
    int finalY = posY + moveY;
    if(finalX < 0 ||
       finalX > 7 ||
       finalY < 0 ||
       finalY > 7 ||
       board[finalY][finalX] != 0)
       return false;
    return true;
}
bool solveKnightTour(int board[N][N], int n, int posX, int posY, int 
moveX[N], int moveY[N])
{
    int next_x, next_y;
    if(n == 65) return true;//when n is equal to 62 the code compiles
    for(int i = 0; i < 8; i ++)
    {
        if(isValidMove(posX, posY, moveX[i], moveY[i], board))
        {
            next_x = posX + moveX[i];
            next_y = posY + moveY[i];
            board[next_y][next_x] = n;
            if(solveKnightTour(board, n + 1, next_x, next_y, moveX, moveY)) 
                 return true;
            else board[next_y][next_x] = 0;
        }
    }
    return false;
}
int main()
{
    int board[N][N];
    int moveX[8] = {1, 1, 2, 2, -1, -1, -2, -2};
    int moveY[8] = {2, -2, 1, -1, 2, -2, 1, -1};
    instArray(board);
    solveKnightTour(board, 2, 0, 0, moveX, moveY);
    printArray(board);
}

没有错误,但是代码似乎无限循环。 在solveKnightTour函数中,当n等于62时,代码将用印制板编译,但是结果不能完全解决骑士巡回赛。

1 个答案:

答案 0 :(得分:1)

由于moveXmoveY数组的排序非常对称,因此您的程序需要很长时间才能找到解决方案。如果将组合按此顺序放置,则会以循环方式遍历方向:

int moveX[8] = {1, 2, 2, 1, -1, -2, -2, -1};
int moveY[8] = {-2, -1, 1, 2, 2, 1, -1, -2};

程序将几乎立即找到解决方案。

在您的代码中,首先搜索“上2向右1”,然后搜索“下2向右1”,然后骑士将沿棋盘顶部曲折,从a8到b6到c8到d6等。沿着板顶部无法访问,程序浪费时间搜索所有这些肯定会失败的组合。

递归回溯是一种效率低下的算法,因为它可以播放大量的组合,因此最初在此处无法使用。 4x4或5x5电路板不会出现这些问题,因为它呈指数级扩展。但是在这种情况下,我提供的答案只能“恰好”起作用。通常,强行使用这种规模的东西往往比您有时间需要更多的计算。

经过编辑以概括/修改答案