java:使用深度优先搜索实现8皇后
我试图实现8皇后使用深度搜索任何初始状态它适用于空板(板上没有女王),但我需要它工作初始状态,如果有一个解决方案,如果没有解决方案初始状态它将打印没有解决方案
这是我的代码:
public class depth { public static void main(String[] args) { //we create a board 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("the solution as pair"); for(int i=0;i<board.length;i++){ for(int j=0;j= N - 1) { int[] a = Backmethod(board, i, j); i = a[0]; j = a[1]; System.out.println("back at (" + i + "," + j + ")"); PrintBoard(board); } //we do the next call 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--) { //search for the last queen if (board[x][y] != 0) { //deletes the last queen and returns the position 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; //check the queens in column for (x = 0; x < board.length; x++) { if (board[i][x] != 0) { return false; } } //check the queens in row for (x = 0; x = 0 && xx >= 0 && xx < board.length && yy = 0 && xx >= 0 && xx < board.length && yy = 0 && xx >= 0 && xx < board.length && 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;
[编辑:添加了条件输出提示。]
添加到@ StephenC的答案:
这是一段复杂的代码,特别是如果你没有编程Java的经验。
我执行了你的代码,它一遍又一遍地反复输出(以及结束)
back at (0,0) 01234567 0 1 Q 2 Q 3 Q 4 Q 5 Q 6 Q 7 Q back at (0,0)
然后崩溃了
Exception in thread "main" java.lang.StackOverflowError at java.nio.Buffer.(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) ...
我的第一直觉总是添加一些System.out.println(...)
以找出出错的地方,但这在这里不起作用。
我看到的唯一两个选择是
- 熟悉调试器并使用它来逐步完成并分析它为什么永远不会停止循环
- 分手吧! 你怎么能希望处理这样一个大问题而不把它分成易消化的块?
更不用说8级皇后的概念开始时很复杂。
还有一个想法:
System.out.println()
s在当前实现时没用,因为它有无限的输出。 调试器在这里是更好的解决方案,但另一种选择是以某种方式限制输出。 例如,在顶部创建一个计数器
private static final int iITERATIONS = 0;
而不是
System.out.println("[ANUMBERFORTRACING]: ... USEFUL INFORMATION ...")
使用
conditionalSDO((iITERATIONS < 5), "[ANUMBERFORTRACING]: ... USEFUL INFORMATION");
这是function:
private static final void conditionalSDO(boolean b_condition, String s_message) { if(b_condition) { System.out.println(s_message); } }
另一种方法是不限制输出,而是将其写入文件 。
我希望这些信息对您有所帮助。
(注意:我编辑了OP的代码是可编译的。)
你问过如何解决它的想法(与解决方案截然不同!)所以,这里有几个提示:
提示#1:
如果在递归程序中得到StackOverflowError
,它可能意味着以下两种情况之一:
- 你的问题太“深”了,或者
- 你的代码中有一个错误导致它无限地递归。
在这种情况下,问题的深度很小(8),所以这必须是一个递归错误。
提示#2:
如果检查堆栈跟踪,您将看到堆栈中每个调用的方法名称和行号。 这……以及一些想法……应该可以帮助你弄清楚代码中的递归模式(如实现的那样!)。
提示#3:
使用调试器Luke ……
提示#4:
如果您希望其他人阅读您的代码,请更加注重风格。 您的缩进在最重要的方法中搞砸了,并且您已经犯了(IMO)不可原谅的错误,忽略了标识符的Java样式规则。 方法名称必须以小写字母开头,类名必须以大写字母开头。
(原则上,我很快就停止了阅读你的代码……)
尝试在for (x = 0; x < board.length - 1; x++)
的行中更改方法IsValid
。
public static boolean IsValid(int[][] board, int i, int j) { int x; //check the queens in column for (x = 0; x < board.length - 1; x++) { if (board[i][x] != 0) { return false; } } //check the queens in row for (x = 0; x < board.length - 1; x++) { if (board[x][j] != 0) { return false; } } //check the queens in the diagonals if (!SafeDiag(board, i, j)) { return false; } return true; }