I am currently trying to learn the topic of Backtracking in Java. It is really really confusing for me because I am stuck.
The problem is to find ways in which N Queens can be placed in NxN Chess board so that none of the Queens can attack each other. A queen can attack in the same row, same column and diagonally. My code goes like this:
import java.util.Scanner;
class Main {
public static void putZero(int[][] board,int n){
for(int i = 0;i<n;i++){
for(int j=0;j<n;j++){
board[i][j]=0;
}
}
}
public static void printBoard(int[][] board,int n){
for(int i = 0;i<n;i++){
for(int j=0;j<n;j++){
System.out.print(board[i][j]);
}
System.out.print("\n");
}
System.out.print("\n\n\n");
}
public static void SolveNQ(int n){
int[][] board = new int[n][n];
putZero(board,n);
if(SolveQUtil(board,0,n)==true){
printBoard(board,n);
}
}
public static boolean isSafe(int row, int col, int[][] board,int n){
int i,j;
for(i=0;i<col;i++){
if(board[row][i]==1)
return false;
}
for(i=row,j = col; i >= 0 && j >= 0; i--, j--){
if(board[i][j]==1)
return false;
}
for (i = row, j = col; j >= 0 && i < n; i++, j--)
if (board[i][j] == 1)
return false;
return true;
}
public static boolean SolveQUtil(int[][] board, int col, int n){
if(col>=n){
return true;
}
else
for(int i=0;i<n;i++){
if(isSafe(i,col,board,n)==true){
board[i][col]=1;
boolean a = SolveQUtil(board,col+1,n);
if(a==true)
return true;
else
board[i][col]=0;
}
}
return false;
}
public static void main(String[] args){
Scanner scan = new Scanner(`enter code here`System.in);
int n = scan.nextInt();;
SolveNQ(n);
}
}
It is producing the result I want, but I am not understanding how this works. In my method SolveQUtil(), the method is called again which is "recursive". When col = 0 is called, the Q1 is placed at [0,0] as there are no existing queens. But when col = 1 is called recursively, it searches for the suitable place and returns 'true'. Now, isn't the SolveNQ() supposed to print the solution every time true is returned? When does it return false? How is this working? I am a beginner and can anyone please explain this to me, step by step? Thank you in advance.
SolveNQ, which does the printing, is not called recursively; SolveQUtil, which SolveNQ calls, and which does not print anything, is recursive.
Related
I have the working code that you can see bellow, I just need someone to help me how to enable user to insert number of queens in a new window and then the program should show all solutions in a new window that will graphically show the chessboard and the queens.
Java program to solve N Queen
Problem using backtracking
public class GfG
{
static int N = 2;
static int k = 1;
/* A utility function to print solution */
static void printSolution(int board[][])
{
System.out.printf("%d-\n", k++);
for (int i = 0; i < N; i++)
{
for (int j = 0; j < N; j++)
System.out.printf(" %d ", board[i][j]);
System.out.printf("\n");
}
System.out.printf("\n");
}
A utility function to check if a queen can
be placed on board[row][col]. Note that this
function is called when "col" queens are
already placed in columns from 0 to col -1.
So we need to check only left side for
attacking queens
static boolean isSafe(int board[][], int row, int col)
{
int i, j;
/* Check this row on left side */
for (i = 0; i < col; i++)
if (board[row][i] == 1)
return false;
/* Check upper diagonal on left side */
for (i = row, j = col; i >= 0 && j >= 0; i--, j--)
if (board[i][j] == 1)
return false;
/* Check lower diagonal on left side */
for (i = row, j = col; j >= 0 && i < N; i++, j--)
if (board[i][j] == 1)
return false;
return true;
}
A recursive utility function
to solve N Queen problem
static boolean solveNQUtil(int board[][], int col)
{
/* base case: If all queens are placed
then return true */
if (col == N)
{
printSolution(board);
return true;
}
/* Consider this column and try placing
this queen in all rows one by one */
boolean res = false;
for (int i = 0; i < N; i++)
{
/* Check if queen can be placed on
board[i][col] */
if ( isSafe(board, i, col) )
{
/* Place this queen in board[i][col] */
board[i][col] = 1;
// Make result true if any placement
// is possible
res = solveNQUtil(board, col + 1) || res;
/* If placing queen in board[i][col]
doesn't lead to a solution, then
remove queen from board[i][col] */
board[i][col] = 0; // BACKTRACK
}
}
/* If queen can not be place in any row in
this column col then return false */
return res;
}
This function solves the N Queen problem using
Backtracking. It mainly uses solveNQUtil() to
solve the problem. It returns false if queens
cannot be placed, otherwise return true and
prints placement of queens in the form of 1s.
Please note that there may be more than one
solutions, this function prints one of the
feasible solutions.
static void solveNQ()
{
int board[][] = new int[N][N];
if (solveNQUtil(board, 0) == false)
{
System.out.printf("Solution does not exist");
return ;
}
return ;
}
// Driver code
public static void main(String[] args)
{
solveNQ();
}
}
I am working on code that uses recursive backtracking to solve the 8 queens problem(placing n chess queens on an n × n board so that none of the queens attack each other).
My task was to create two methods:
Write a public solveQueens(int n) method to solve the problem for an nxn board
Write a private recursive placeQueen(board, column) method to attempt to place a queen in the specified column.
So far I have written this in my program:
public class Queen {
public static boolean isLegal(int[] board, int n) {
for (int i = 0; i < n; i++) {
if (board[i] == board[n]) {
return false;
}
if ((board[i] - board[n]) == (n - i)) {
return false;
}
if ((board[n] - board[i]) == (n - i)) {
return false;
}
}
return true;
}
public static void solver(int n) {
int[] board = new int[n];
PlaceQueen(board, 0);
}
private static int[] PlaceQueen(int[] board, int column) {
int n = board.length;
if (column == n); else {
for (int row = 0; row < n; row++) {
board[column] = row;
if (isLegal(board, column)) {
PlaceQueen(board, column + 1);
}
}
}
return (board);
}
public static void main(String[] args) {
int n = Integer.parseInt(args[0]);
solver(n);
}
}
My program successfully compiles, but whenever I try to run it, I get this error.
Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 0
at Queen.main(Queen.java:39)
Any suggestions on feedback on where I should edit my code to get rid of this Exception?
Do you provide a argument to the program ?
It expects to have a integer argument.
public static void main(String[] args) {
int n = Integer.parseInt(args[0]);
solver(n);
}
If you try to access to an index which is not in the range of the args array, it rises java.lang.ArrayIndexOutOfBoundsException
Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 6 years ago.
Improve this question
UPDATED CODE: My last question is how do I get it so that my program prints all 92 solutions of an 8x8 board, without any Queens attacking each other? So far, my code only prints 1 solution. For example, when I change it to a 4x4 board, I only have 1 solution, when there should be 2 I believe.
public class Queen{
public static void display(int[] board){
int n = board.length;
for(int column = 0; column < n; column++){
for(int row = 0; row < n; row++){
if(board[column] == row)
System.out.print('Q');
else
System.out.print('x');
}
System.out.print('\n');
}
}
public static int[] solveQueens(int n){
int board[] = new int[n];
placeQueen(board,0);
return board;
}
private static boolean placeQueen(int[] board, int column){
int n = board.length;
if (n == column){
return true;
}else{
for (int row = 0; row < n; row++){
int i; //remove
for (i = 0; i < column; i++){ //for (int i)
if (board[i] == row || i - column == board[i] - row || column - i == board[i] - row){
break;
}
}
if (i == column){
board[column] = row;
if (placeQueen(board, column + 1))
return true;
}
}
}
return false;
}
public static void main(String args[]){
int finished[] = solveQueens(8);
display(finished);
}
}
Now my programs returns:
Qxxxxxxx
xxxxQxxx
xxxxxxxQ
xxxxxQxx
xxQxxxxx
xxxxxxQx
xQxxxxxx
xxxQxxxx
OLD CODE:
I need to use recursive backtracking to solve the 8-queens problem. The n-queens problem is a puzzle that requires placing n chess queens on an n × n board so that none of the queens attack each other.
I need to Write a public solveQueens(int n) method to solve the problem for an nxn board
I also need to write a private recursive placeQueen(board, column) method to attempt to place a queen in the specified column.
This is my code so far:
public class Queen{
public static int[] solveQueens(int n){
int board[] = new int[n];
int finished[] = placeQueen(board,0);
return finished;
}
private static int[] placeQueen(int[] board, int column){
int n = board.length;
int row = column;
if (n == column){
return board;
}else{
for (row = n; row < n; row++){
board[column] = row;
if (board[n] == 0 && board[n-1] == 0 && board[n+1] == 0){
board[n] = 1;
placeQueen(board, column+1);
}
}
for (row = n; row < n; row++){
board[row] = column;
if (board[n] == 0 && board[n-1] == 0 && board[n+1] == 0){
board[n] = 1;
placeQueen(board, column+1);
}
}
}
return board;
}
public static void main(String args[]){
int finished[] = solveQueens(8);
for (int item: finished){
System.out.print(item);
}
}
}
Whenever I run my program, all it returns is
----jGRASP exec: java Queen
00000000
Is there any explanation on how to setup my 8x8 board, and how to place queens so they don't attack each other?
I made some changes in solveQueens and placeQueen:
public class Queen{
public static int[] solveQueens(int n){
int board[] = new int[n];
placeQueen(board,0); //it fills the board
return board;
}
private static boolean placeQueen(int[] board, int column){
int n = board.length;
int row;
if (n == column){
return true;
}else{
for (row = 0; row < n; row++){
int c;
for (c=0; c<column; c++){
if (board[c]==row || c-column==board[c]-row || column-c==board[c]-row){
//check if it is safe position (we know 2 queens couldn't place in a same column or row or diameter
break;
}
}
if (c==column){ //if previous loop didn't break...=> it is safe position
board[column]=row;
if (placeQueen(board, column+1)) //if it is possible to fill the rest of board //else: test the next row
return true;
}
}
}
return false;
}
public static void main(String args[]){
int finished[] = solveQueens(8);
for (int item: finished){
System.out.print(item);
}
}
}
below is my code and I don't know where I got wrong
It compiled well works well but, doesn't print the right result;;;
if N is 4 , the result should be
2 4 1 3
However, It printed
1 3 0 0
I guess there are something wrong in for-loop because when I do it with another value like 5 it also printed only two numbers
this is the result from N=5;
1 4 0 0 0
import java.util.Scanner;
public class NQueens{
public static int N ;
public static int [] cols;
public static void printcols(){
for(int i =1; i<=N; i++){
System.out.print(cols[i] + " ");
}
System.out.print("\n");
}
public static boolean promising(int level){
for(int i =1; i<level ; i++){
if(cols[i] == cols[level]){
return false;
}else if(level-i == Math.abs(cols[level]- cols[i]))
return false;
}
return true;
}
public static boolean queens(int level){
if(!promising(level)){
printcols();
return false;
}
else if(level == N){
printcols();
return true;
}
for(int i =1; i<N; i++){
cols[level+1] = i;
if(queens(level+1)){
return true;
}
}
return false;
}
public static void main(String []args){
Scanner sc = new Scanner(System.in);
N = sc.nextInt();
cols = new int [N+1];
queens(0);
}
}
It does not just print 1 3 0 0, but prints every backtracking step, and at the end it doesn't find any solutions. The problem is that you are mixing 0-based and 1-based indices, and eventually made an error.
In the following line:
for(int i =1; i<N; i++){
you are iterating over only N-1 possibilities, leaving i == N out. So the fix is just to allow equality too:
for(int i =1; i<=N; i++){
With this modification the program works as intended.
I'm testing a part of my Sudoku program to test if the row is valid or not. The board from file method makes a 9x9 array, but I can't understand why when I try running this isValidRow() method there is no indication of it being true or false. Why is this so?
public static boolean isValidRow(int[][] grid, int row) {
int i = 0;
int j = 0;
while (i < 9){
while (j < 9){
if (grid[row][i] == grid[row][j]){
if (i == j){
continue;
}
return false;
}
j++;
}
i++;
}
System.out.println("hii");
return true;
}
public static void main(String[] args) throws IOException {
int[][] board = new int[9][9];
boardFromFile(board, "sudoku.txt");
System.out.println(isValidRow(board, 0));
}
You have an infinite loop in isValidRow().
When you first call this function i and j are both zero (0). Thus,
if (grid[row][i] == grid[row][j])
will always evaluate to true. As will:
if (i == j)
The next action is:
continue;
which will start the inner while loop again. And as i and j are unchanged the same thing will happen again and again.