This problem dates back to Max Bezzel in 1848, and it has drawn the interest of many mathematicians since then.
N queens is also a nice example of using recursion to implement a depth-first backtracking algorithm (similar to Sudoku, which we will cover next week as another example) with a few tricks can avoid the entire search space. For example, for an 8x8 board there are over 4.4 ** billion ** possible arrangements (64 chose 8) but if we chose one queen per column (row) it reduces to over 16.7 million (8^8).
It also is a good example where using more efficient coding (inc. what is often called branch and bound) will substancially reduce the overall run time.
Develop a simple C++ program called "nqueens.cpp" that takes a single command line argument, which will be size of the chess board.
The n-queens problem is pretty simple. We want to find boards of size n x n with a total of n queens on it with a wrinkle: none of the queens on these boards threaten each other. This means there is no other queen in the same row, nor the same column, and there are no queens on either diagonal relative to the all of the n queens placed.
You must implement a simple C++ function called n queens with the following parameters:
As alluded to above, we will implement the more efficient version where each element of the 1D vector is the row-position of a queen at that specific column. For example, if board[2] is 5, that means there is a queen in the third column in the 6th row (assuming we count from 0)
The simplest recursive/backtracking solution calls the nqueens function as follows from main:
nqueens (Board, 0, size);
And there are two conditions in the brute-force version to consider:
for (int i = 0; i < size; i++) { board[pos] = i; nqueens (board, pos + 1, size); }
For example, calling your program as follows:
./nqueens 8
should output the following:
0, 4, 7, 5, 2, 6, 1, 3 0, 5, 7, 2, 6, 3, 1, 4 0, 6, 3, 5, 7, 1, 4, 2 0, 6, 4, 7, 1, 3, 5, 2 ... (there are 92 total, of which 4 have queens at 0,0)
Hint: You can compute the difference between the rows of
two queens (aka the values) and the difference between the columns of the
queens (aka the indices of the array) to help locate other queens on the
same diagonal. Draw it out to see what we mean.
The simple recursive backtracking above will enumerate (and check) all of the possibilities. This is over 16.7 million for a board of size 8, which even with a relatively inefficient check takes a few seconds on a tesla lab machine. It will work less well, however, with larger boards. As a concrete example, a 10x10 board generates over 1.41 billion possibilties and checking each of these takes a little over 2.5 minutes on tesla1 using my (SJE) most efficient solution.
Create a second version of nqueens (called nqueens2.cpp) that will only check additonal columns if the current board is valid. For example, using my code above in the second iteration the function will happily place another queen down in the first row (0) even though the prior iteration already placed a row there. Please count the total number of boards checked and display that to standard error (so make test will still work) so you can submit this to us in the report.
There will be no extra credit or special challenges this week.
+ 2 nqueens.cpp and nqueens2.cpp are well formatted, commented (inc. name, assignment, and overview), with reasonable variable names +8 Finds all 92 solutions for n=8 based on make test +8 Finds all 724 solutions for n=10 based on make test +9 Implements constrained backtracking for part 2 +8 Report (report.txt) has the requested values. Namely: - # of Boards considered with contraint(s) for n = 8 - # of Boards considered with contraint(s) for n = 10 - In your own words, what is the benefit of a recursive solution to enumerate all of the nqueens potential solutions (2 points) - Also in your own words, what are the theoretical and/or practical advantages of constraining the search space to only still valid solutions?
If you have implemented only contrained backtracking we'll accept it for make test if you make a note of it in the report.txt **BUT ** it must output the solutions in the same order as our reference answers.
To faciliate testing, you were previously asked to clone the course Github repository as follows:
git clone https://github.com/semrich/CS202-22.git cs202
For this assignment, update this clone by using the following:
git pull
Name your solution to part 1 "nqueens.cpp," the solution to part 2, "nqueens2.cpp." Name your report "report.txt."
Then, please run the following command prior to submission:
tar -cvf lab7.tar nqueens.cpp nqueens2.cpp report.txt
Note: Although submission will be faciliated by Canvas, we will compile and test on EECS lab machines!
If you develop your solution elsewhere please make sure it works on
the lab computers prior to the deadline.