我尝试使用深度优先搜索来实现8皇后问题,对于初始状态为空棋盘(棋盘上没有皇后)时它工作得很好,但我需要它能够处理有初始状态的情况,如果该初始状态有解,它应该找到解,如果没有解,它应该打印出没有解的信息。
这是我的代码:
public class depth { public static void main(String[] args) { //我们创建一个棋盘 int[][] board = new int[8][8]; board [0][0]=1; board [1][1]=1; board [2][2]=1; board [3][3]=1; board [4][4]=1; board [5][5]=1; board [6][6]=1; board [7][7]=1; eightQueen(8, board, 0, 0, false); System.out.println("解的坐标对"); for(int i=0;i<board.length;i++){ for(int j=0;j<board.length;j++) if(board[i][j]!=0) System.out.println(" ("+i+" ,"+j +")"); } System.out.println("存储在内存中的节点数 "+count1); } public static int count1=0; public static void eightQueen(int N, int[][] board, int i, int j, boolean found) { long startTime = System.nanoTime();//开始计时 if (!found) { if (IsValid(board, i, j)) {//检查位置是否有效 board[i][j] = 1; System.out.println("[在 (" + i + "," + j + ") 处添加了皇后"); count1++; PrintBoard(board); if (i == N - 1) {//检查是否是最后一个皇后 found = true; PrintBoard(board); double endTime = System.nanoTime();//结束计时 double duration = (endTime - startTime)*Math.pow(10.0, -9.0); System.out.print("总时间"+"= "+duration+"\n"); } //调用下一步 eightQueen(N, board, i + 1, 0, found); } else { //如果位置无效且到达最后一行,我们进行回溯 while (j >= N - 1) { int[] a = Backmethod(board, i, j); i = a[0]; j = a[1]; System.out.println("回溯到 (" + i + "," + j + ")"); PrintBoard(board); } //进行下一次调用 eightQueen(N, board, i, j + 1, false); } }}public static int[] Backmethod(int[][] board, int i, int j) { int[] a = new int[2]; for (int x = i; x >= 0; x--) { for (int y = j; y >= 0; y--) { //搜索最后一个皇后 if (board[x][y] != 0) { //删除最后一个皇后并返回位置 board[x][y] = 0; a[0] = x; a[1] = y; return a; } } } return a;}public static boolean IsValid(int[][] board, int i, int j) { int x; //检查列中的皇后 for (x = 0; x < board.length; x++) { if (board[i][x] != 0) { return false; } } //检查行中的皇后 for (x = 0; x < board.length; x++) { if (board[x][j] != 0) { return false; } } //检查对角线上的皇后 if (!SafeDiag(board, i, j)) { return false; } return true;}public static boolean SafeDiag(int[][] board, int i, int j) { int xx = i; int yy = j; while (yy >= 0 && xx >= 0 && xx < board.length && yy < board.length) { if (board[xx][yy] != 0) { return false; } yy++; xx++; } xx = i; yy = j; while (yy >= 0 && xx >= 0 && xx < board.length && yy < board.length) { if (board[xx][yy] != 0) { return false; } yy--; xx--; } xx = i; yy = j; while (yy >= 0 && xx >= 0 && xx < board.length && yy < board.length) { if (board[xx][yy] != 0) { return false; } yy--; xx++; } xx = i; yy = j; while (yy >= 0 && xx >= 0 && xx < board.length && yy < board.length) { if (board[xx][yy] != 0) { return false; } yy++; xx--; } return true;}public static void PrintBoard(int[][] board) { System.out.print(" "); for (int j = 0; j < board.length; j++) { System.out.print(j); } System.out.print("\n"); for (int i = 0; i < board.length; i++) { System.out.print(i); for (int j = 0; j < board.length; j++) { if (board[i][j] == 0) { System.out.print(" "); } else { System.out.print("Q"); } } System.out.print("\n"); }}}
例如,对于这个初始状态,它会给我以下错误:
Exception in thread "main" java.lang.StackOverflowError
我卡住了,我认为错误是方法的无限调用,如何解决这个问题?
任何建议都会有帮助,提前感谢。
注意:棋盘是一个二维数组,当我放置(1)时,表示该位置有皇后。
注意2:当我将初始状态设置为以下时,它可以工作:
board [0][0]=1; board [1][1]=1; board [2][2]=1; board [3][3]=1; board [4][4]=1; board [5][5]=1; board [6][6]=1; board [7][1]=1;
回答:
[EDIT: 添加了条件输出提示。]
补充@的回答:
这是一个非常复杂的代码片段,特别是如果你对编写Java程序不熟练的话。
我执行了你的代码,它不断地输出以下内容(反复多次):
back at (0,0) 0123456701 Q2 Q3 Q4 Q5 Q6 Q7 Qback at (0,0)
然后崩溃并显示以下错误:
Exception in thread "main" java.lang.StackOverflowError at java.nio.Buffer.<init>(Unknown Source) ... at java.io.PrintStream.print(Unknown Source) at java.io.PrintStream.println(Unknown Source) at Depth.eightQueen(Depth.java:56) at Depth.eightQueen(Depth.java:60) at Depth.eightQueen(Depth.java:60) at Depth.eightQueen(Depth.java:60) at Depth.eightQueen(Depth.java:60) ...