java:使用深度优先搜索的8个皇后

时间:2014-01-30 15:38:04

标签: java n-queens

我实现了深度优先搜索8皇后,它适用于空板,但我需要修改它以接受任何初始状态。我修改了它,但它给出了一个错误。我不知道如何解决这个问题。

这是我的代码:

public class depth {
    public static int count1=0;
    public static void eightQueen(int N, int[][] board, int i, int j, boolean found) {

        long startTime = System.nanoTime();//time start

        if (!found) {

            if (IsValid(board, i, j)) {//check if the position is valid
                board[i][j] = 1;

                System.out.println("[Queen added at (" + i + "," + j + ")");
                count1++;
                PrintBoard(board);


                if (i == N - 1) {//check if its the last queen
                    found = true;
                    PrintBoard(board);
                    double endTime = System.nanoTime();//end the method time

                    double duration = (endTime - startTime)*Math.pow(10.0, -9.0);
                    System.out.print("total Time"+"= "+duration+"\n");
                }
                //call the next step
                eightQueen(N, board, i + 1, 0, found);
            } else {

                //if the position is not valid & if reach the last row we backtracking 
                while (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 < board.length; x++) {
            if (board[x][j] != 0) {
                return false;
            }
        }
        //check the queens in the diagonals
        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");
        }
    }

    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<board.length;j++)
                if(board[i][j]!=0)

                System.out.println("  ("+i+" ,"+j +")");
        }
        System.out.println("the number of node stored in memory "+count1);    
    }
}

这是错误:

 Exception in thread "main" java.lang.StackOverflowError

它不适用于任何初始状态。我不知道问题出在哪里,如果找不到任何解决方案,我需要打印“无解决方案”。

2 个答案:

答案 0 :(得分:1)

方法eightQueen无限期地调用自己。

答案 1 :(得分:1)

此代码导致死锁,其中相同的函数继续以递归方式调用。 方法:eightQueen检查位置(i,j)是否有效。在您的情况下,i和j的第一个值分别为(0,0)。

它递增j直到达到7然后返回第一个大写位置(0,0)。 else循环永远不会增加i,并且所有可用位置都是不安全的,因此它最终会进入无限循环。

您需要重新访问代码。