Java: 8 ферзей с использованием поиска в глубину

Я реализовал поиск в глубину для 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

Он не работает ни для какого начального состояния. Я не знаю, где проблема, и мне нужно, чтобы она печатала «нет решения», если она не находит никакого решения.


person john    schedule 30.01.2014    source источник
comment
Никто не собирается сидеть здесь и перебирать за вас весь этот код. Вот почему Бог создал отладчики. Если у вас есть переполнение стека, то ваш рекурсивный метод не имеет условия выхода и вызывает сам себя навсегда.   -  person OldProgrammer    schedule 30.01.2014
comment
я использую отладчик, я знаю ошибку, но я не знаю, как это исправить   -  person john    schedule 30.01.2014
comment
Примечание для тех, кто столкнулся с этим вопросом в очереди голосов: несмотря на то, что он был опубликован первым, я проголосовал за его закрытие, потому что на второй есть принятый ответ.   -  person Adi Inbar    schedule 02.02.2014


Ответы (2)


Этот код приводит к тупиковой ситуации, когда одна и та же функция продолжает вызываться рекурсивно. Метод: восемьQueen проверяет правильность местоположения (i,j). В вашем случае первые значения для i и j равны (0,0) соответственно.

Он увеличивает j, пока не достигнет 7, а затем возвращает первую позицию ферзя (0,0). Цикл else никогда не увеличивает i, и все доступные местоположения небезопасны, поэтому он заканчивается бесконечным циклом.

Вам нужно пересмотреть код.

person user2881767    schedule 30.01.2014
comment
Я не знал, как это исправить, вы можете мне помочь? - person john; 30.01.2014
comment
Ваш код ожидает хотя бы одну доступную позицию. В вашем тестовом сценарии необходимо изменить все 8 начальных позиций, так как у первого ферзя нет места. Текущий код будет работать для всех условий, таких как {1,1,1,1,1,1,1,0} - person user2881767; 31.01.2014
comment
Можете ли вы помочь мне, отредактировав код для печати, нет решения, если нет места для размещения королевы, спасибо. - person john; 31.01.2014

Метод eightQueen вызывает себя бесконечно.

person Happy    schedule 30.01.2014
comment
спасибо за ответ, как это исправить. - person john; 30.01.2014