【问题标题】:Knights tour backtracking Java骑士之旅回溯Java
【发布时间】:2014-01-12 01:57:31
【问题描述】:

我正在尝试使用 java 中的回溯和递归解决 4x4 板上的骑士之旅问题,并且在输出中我得到以下步骤顺序:

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();
}
}

【问题讨论】:

  • 我对骑士之旅不熟悉,所以我用谷歌搜索了它,first result 提出了一个论坛帖子......其中第三个答案是“骑士不能游览 4x4 board”...我不确定这是否真的不可能...但我会在尝试对其进行编码之前找出答案 XD
  • 我在 8x8 板上遇到了同样的问题
  • 是的,看看this image,您只能访问路径图像左侧或右侧的所有四个字母一次,不能同时访问。

标签: java recursion backtracking knights-tour


【解决方案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 &gt;= 4)。请改用数组的大小或final 值。

【讨论】:

  • 您能编辑/修改整个代码吗?因为我已经绝望了
【解决方案2】:

您的 tour() 函数似乎将正方形的值设置为第一次访问的订单的计步器。但是您正在尝试多种选择。当您到达 12 时,您的第一次巡回赛死路一条 - 随后的一次尝试触及 13-16 格中的每一个。

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-08-07
    • 1970-01-01
    • 2023-01-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多