Knight's Tour 代码陷入无限循环,无法解决
Posted
技术标签:
【中文标题】Knight\'s Tour 代码陷入无限循环,无法解决【英文标题】:Knight's Tour code runs into infinite loop, does not reach a solutionKnight's Tour 代码陷入无限循环,无法解决 【发布时间】:2018-12-25 06:22:29 【问题描述】:我对 Knight's Tour 的递归回溯方法陷入了无限循环。起初,我认为这个问题通常可能会花费这么多时间,但有些解决方案会立即解决。请告诉我的代码有什么问题。
package io.github.thegeekybaniya.InterviewPrep.TopTopics.Backtracking;
import java.util.Arrays;
public class KnightsTour
private static int counter=0;
public static void main(String[] args)
knightsTour(8);
private static void knightsTour(int i)
int[][] board = new int[i][i];
for (int[] arr :
board)
Arrays.fill(arr, -1);
board[0][0] = 0;
knightsTour(board,0,1);
private static boolean knightsTour(int[][] board, int cellno, int stepno)
if (stepno == board.length * board.length)
printBoard(board);
return true;
int[][] dirs =
1, 2, 1, -2, -1, 2, -1, -2, 2, 1, 2, -1, -2, 1, -2, -1
;
int row = cellno / board.length, col = cellno % board.length;
for (int i = 0; i < dirs.length; i++)
int r = dirs[i][0] + row;
int c = dirs[i][1] + col;
if (isSafe(board, r, c)&&board[r][c]==-1)
int ncell = r * board.length + c;
board[r][c] = stepno;
if (knightsTour(board, ncell, stepno + 1))
return true;
else
board[r][c] = -1;
return false;
private static boolean isSafe(int[][] board, int r, int c)
return r >= 0 && c >= 0 && r < board.length && c < board.length;
private static void printBoard(int[][] board)
System.out.println(++counter);
for (int i = 0; i < board.length; i++)
for (int j = 0; j < board.length; j++)
System.out.print(board[i][j]+" ");
System.out.println();
【问题讨论】:
该函数不是递归的,也不是迭代的,它不需要任何停止条件。 调试的时候有没有发现什么,一步步去看看它在做什么? 是的,我在进行递归调用之前通过添加打印语句对其进行了调试。工作正常,走步正常,遇到死角后回溯。 【参考方案1】:您的代码中没有错误,只是蛮力方法很慢,因为搜索空间很大。您可以通过实现Warnsdorf's Rule 来加快搜索速度。这是选择下一步行动的启发式方法,您总是尝试在之后的下一步行动中产生最少可用行动的行动。可以通过几个简单的循环来完成:
int row = cellno / board.length, col = cellno % board.length;
// find move with fewest moves available for the next move:
int minMovesAvailable = 8;
int minMovesDir = 0;
for (int i = 0; i < dirs.length; i++)
int r = dirs[i][0] + row;
int c = dirs[i][1] + col;
if (isSafe(board, r, c)&&board[r][c]==-1)
board[r][c] = stepno;
int movesAvailable = 0;
for (int j = 0; j < dirs.length; j++)
int r2 = dirs[j][0] + r;
int c2 = dirs[j][1] + c;
if (isSafe(board, r2, c2)&&board[r2][c2]==-1)
movesAvailable++;
board[r][c] = -1;
if(movesAvailable < minMovesAvailable)
minMovesAvailable = movesAvailable;
minMovesDir = i;
// now recurse this move first:
// int r = dirs[minMovesDir][0] + row;
// int c = dirs[minMovesDir][1] + col;
【讨论】:
以上是关于Knight's Tour 代码陷入无限循环,无法解决的主要内容,如果未能解决你的问题,请参考以下文章
Knight's tour backtrack 实现选择步长数组