N-Queens not printing all solutions

Spindoctor :

I'm new to recursion and backtracking. I am trying to complete the N-Queen problem to print all solutions instead of just 1 and to understand these concepts.

I think I have the algorithm implemented partially right as I get some of the solutions but not all printed. My code is in Java.

  • For a value of N = 4, I get 2 solutions - this is right
  • For a value of N = 5, I get 5 solutions - there are actually 10
  • For a values of N= 8, I get none printed

I cannot figure out what mistake I am making. The idea I have is to realize that the 1st queen has to go in the first row, 2nd in the second row etc.I have to figure out which column is appropriate obviously taking care of diagonals to place a queen.

Any help in pointing me in the right direction is appreciated. My code is below and I have tried to add comments so that it helps with understanding.

public class nQueens {

    static class Queen {
        public Queen( int row, int column) {
            this.row = row;
            this.column = column;
        }
        int row = -1;
        int column = -1;
    }

    static ArrayList<Queen> queens = new ArrayList<Queen>();

    public static void main(String argv[]) {
        int n = 5;
        int[][] chessBoard = new int[n][n];
        int placed = 0;
        solve(n, chessBoard, placed);
    }

    public static void solve(int n, int[][] chessBoard, int placed) {
        // this means that all the queens have been placed
        if (placed == n) {
            System.out.println("**** Solution *****");
            for (int i = 0; i < n; i++) {
                for (int j = 0; j < n; j++) {
                    System.out.print(chessBoard[i][j] + " ");
                }
                System.out.println();
            }
        } else {
            // we know that each queen can be placed on each row
            int i = placed;
            // iterate through the columns
            for (int j = 0; j < n; j++) {
                if (chessBoard[i][j] != 1) {
                    if (isSafe(i, j)) {
                        chessBoard[i][j] = 1;
                        Queen queen = new Queen( i, j);
                        queens.add(queen);
                        placed = placed + 1;
                        // solve for the remaining number of queens
                        solve(n, chessBoard, placed);
                        // un-mark the spot
                        chessBoard[i][j] = 0;
                        // remove the placed queen
                        queens.remove(queens.size() - 1);
                        placed = placed - 1;
                    }
                }
            }
        }
    }

    public static boolean isSafe(int row, int column) {
        // this means that there are no queens on the board
        if (queens.isEmpty()) {
            return true;
        } else {
            for (int i = 0; i < queens.size(); i++) {
                // same column
                if (queens.get(i).column == column) {
                    return false;
                }
                // check diagonal
                int slope = Math.abs((queens.get(i).row - row) / (queens.get(i).column - column));
                if (slope == 1) {
                    return false;
                }
            }
        }
        return true;
    }
}
Primusa :

The problem is:

int slope = Math.abs((queens.get(i).row - row) / (queens.get(i).column - column));
if (slope == 1) {
    return false;
}

You're casting slope to an integer. This means that a slope of 1.5 or 1.3 becomes 1 and results in you returning false even though a queen isn't actually on that diagonal.

Instead cast to float before the division (note that java's division is integer division so you need to cast either the divisor or the dividend to a float first to get a float output) to allow for floating point slopes:

float tmp = (queens.get(i).row - row);
float slope = Math.abs(tmp/ (queens.get(i).column - column));
if (slope == 1) {
    return false;
}

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=152257&siteId=1