骑士之旅回溯Java

时间:2013-12-23 20:10:49

标签: java recursion backtracking

我正试图在4x4板上用java中的回溯和递归来解决Knights巡演问题,并且在输出中我得到了这一步序列:

1 13 16 15
10 7 4 14
5 2 11 8
12 9 6 3

在右上角,14,15和16彼此相邻,这是不可能的,因为骑士在棋盘上移动成L形。如果有人能帮我解决这个问题,我将感激不尽。

代码:

public class KnightsTour {

private static int board[][] = new int[4][4];
private static int stepCounter = 1;

public Test() {
    initBoard(board);
    tour(0,0);
    printSol(board);

}

  public static void printSol(int[][] a) {
    for (int i = 0; i < a.length; i++) {
        for (int j = 0; j < a[i].length; j++) {
            if(a[i][j]>9){
                System.out.print(a[i][j] + "  ");
            }else{
                System.out.print(a[i][j] + "   ");
            }
        }
        System.out.println();
    }
    System.out.println();
}


public static void initBoard(int[][] a) {
    for (int i = 0; i < a.length; i++) {
        for (int j = 0; j < a[i].length; j++) {
            a[i][j] = -1;
        }
    }
}


public void tour(int x, int y) {


    if (((x < 0) || (x >= 4) || (y < 0) || (y >= 4)) || (board[x][y] != -1)) {
        return;
    }else{
        board[x][y] = stepCounter++;
        tour(x+2, y+1);
        tour(x+1, y-2);
        tour(x+1, y+2);
        tour(x-1, y+2);
        tour(x-2, y-1);
        tour(x-2, y+1);
        tour(x-1, y-2);
        tour(x+2, y-1);  
    }
}




public static void main(String[] args){
    new KnightsTour();
}
}

2 个答案:

答案 0 :(得分:1)

  • 您需要使函数返回一个布尔值,以便它可以告诉调用函数它是否成功。否则,只要你已经尝试了所有可能的组合,即使你已经找到解决方案,你也会继续。

    然后,在每次调用函数时,您需要检查返回值,如果成功则返回true。

    然后你显然需要在完成时返回true。

    我建议像:

    if (stepCounter == 1 + board.length * board[0].length)
      return true;
    

    board[x][y] = stepCounter++;之后。

  • 您需要还原在函数调用结束时所做的任何更改,即stepCounter需要减少,board[x][y]需要设置为-1

成功完成这些更改之后,您应该看到所有-1的结果,因为在4x4电路板上不可能,但将其更改为8x8应该会成功。

请注意,我之前没有使用17 - 最好不要使用硬编码值(例如,x >= 4)。请使用数组的大小或final值。

答案 1 :(得分:0)

您的tour()函数似乎将广场的值设置为首次访问的订单的步数计数器。但是你正在尝试多种选择。当你到达12时,你的第一个旅行死亡结束 - 随后的一次尝试触及13-16个方格中的每一个。

您需要存储当前游览的状态,而不是您访问的顺序。例如。如果你回溯,当前的广场不再是巡演的一部分。如果你找到一个旅游,你应该停下来,因为你已经完成了。