Two solutions and code for Queen n-Java and C ++

Source: Internet
Author: User

Two solutions and code for Queen n-Java and C ++

 

Abstract: This article focuses on the ideas for solving the n queen problem, and implements the process using java and c ++ respectively. Finally, bitwise operations are used for Algorithm Improvement.

I. Question throwing and preliminary solutions

Problem description: the eight queens question is a question with the background of chess: how can we place eight queens on the 8x8 chess board, so that no queen can directly eat any other queen? For this purpose, neither queen can be in the same horizontal, vertical, or diagonal line.

Conversion rules: in fact, the eight queens problem can be promoted to the more general n queens placement problem: the size of the board changes to n × n, and the number of Queens also changes to n. The problem is resolved only when n = 1 or n is greater than or equal to 4. Save an array a [n, a [I] indicates the number of columns that place the queen I on the row I (note that the I value is calculated from 0 ), the following is a simple process from rule to problem extraction for the eight queens issue.

 


(1) because all queens cannot be placed in the same column, there cannot be two identical values in the array.
(2) All queens cannot be on the diagonal lines. How can we check whether two queens are on the same diagonal line? We will generate a two-dimensional array of the checker Square, as shown below:

 

 

Assume that two queens are placed in the positions of (I, j) and (k, l). Obviously, only when | I-k | = | j-l | is used, the two queens are on the same diagonal line.

 

Ii. Code and Result

 

(1) C ++ version

Running platform: VS2013

Operating System: Windows 7

 

/*** @ Author lin **/# include
 
  
# Include
  
   
# Include
   
    
Using namespace std;/** Number of Queens */static int num;/** subscript I indicates the row number, and x [I] indicates the location of the queen of row I, note that */static int * x is not required for the 0 rows here;/** number of solutions */static int sum = 0; /*** determine the location where the queen of the k row can be placed * @ param k indicates the k row, X [K] k indicates the position of the Queen on the k line * @ return boolean false indicates that the queen cannot be placed here */bool place (int k) {for (int j = 1; j <k; j ++) {/* If the position of the Queen on the K row currently passed in is a diagonal line with that of the other queen (abs (x [k]-x [j]) = abs (k-j) or a straight line (x [j] = x [k]) */if (abs (x [k]-x [j]) = abs (k-j) | x [j] = x [k]) {return (false) ;}} return (true );} /*** determine the Queen location of a row * @ param t */void backtrack (int t) {if (t> num)/* if the current row is greater than the queen's number, indicates that */{sum ++ is found;/* is printed to the location of the Resolution queen in sequence */for (int m = 1; m <= num; m ++) {// cout <x [m];/* when this line is output to the leaf node recursively, A feasible solution * // write the following for (int k = 1; k <= num; k ++) only for good looks) {if (k = x [m]) {cout <x [m] <;}else {cout <*; // use * to indicate the location that is not used} cout <endl ;}cout <endl ;}else {for (int I = 1; I <= num; I ++) {x [t] = I;/* place the emperor at the top of row t in column I */if (place (t )) {/* The place function here is used to judge the conditions we mentioned above. If it is true, go to the next level of recursion */backtrack (t + 1) ;}}} int main () {cout <enter the number of Queens:; cin> num; clock_t start, finish; double totaltime; // calculate the program running time start = clock (); // start time x = new int [num + 1];/* Add 1 here, where 0 rows are not used, and 1-num correspond to 1-num rows */for (int I = 0; I <= num; I ++) x [I] = 0; backtrack (1);/* pass in the first queen, start recursion */cout <total scheme <sum; delete [] x; finish = clock (); // End Time totaltime = (double) (finish-start) /CLOCKS_PER_SEC; cout <the running time of this program is <
    
     
Output result:
     

 

8 Queens:

Queen 10:

 

(2) java version

 

Running platform: eclispse luna

Operating System: Windows 7

Package com. lin; import java. lang. *;/*** solve the n queen problem * @ author lin **/public class QueenTest {/** subscript I indicates the row number, x [I] indicates the position of the queen of line I. Note that */public int [] x is not required for line 0 here;/** Number of Queens */public int queenNum; /** number of solutions */public int methodNum; QueenTest (int queenNum) {this. queenNum = queenNum; this. x = new int [queenNum + 1]; // note that backtrack (1) is not required for the first row starting from row 1st ); // recursively start from the first queen}/** determine the location of the queen in a row * @ param t */public void backtrack (int t) {if (t> queenNum) // if the current row is greater than the queen's number, the solution {methodNum ++ is found; // sum is all feasible solutions. // print the location of the Resolution queen in sequence for (int m = 1; m <= queenNum; m ++) {// System. out. println (x [m]); // This row is output when it is recursive to the leaf node, A feasible solution // write the following for (int k = 1; k <= queenNum; k ++) {if (k = x [m]) only for good looks. {System. out. print (x [m] +);} else {System. out. print (*); // use * to indicate the location that is not used} System. out. println ();} System. out. println () ;}else {for (int I = 1; I <= queenNum; I ++) {x [t] = I; // The Queen's position on Line t can only be 1-queenNum if (place (t) {// The place function here is used to judge the conditions we mentioned above. if so, go to the next level of recursion, that is, place the next queen backtrack (t + 1 );}}}} /*** determine the location where the queen of the k row can be placed * @ param k indicates the k row, X [K] k indicates the position of the Queen on the k line * @ return boolean false indicates that the queen cannot be placed here */public boolean place (int k) {for (int j = 1; j <k; j ++) // if the position of the Queen on the K row currently passed in is a diagonal line with the other queen (abs (x [k]-x [j]) = abs (k-j) or a straight line (x [j] = x [k]) if (Math. abs (x [k]-x [j]) = Math. abs (k-j) | (x [j] = x [k]) {return false;} return true;} public static void main (String [] args) {QueenTest queenTest = new QueenTest (8); System. out. println (total number of solutions: + queenTest. methodNum );}}

Output result:

This is the queen of eight.

This is the tenth queen:
Compared with java and C ++, we found that java is faster to run? Why? The reason is that C ++ uses the new operation, while java basically creates data on the stack, and the access speed is much faster than the heap.3. More efficient algorithms-bit operation version

The method above has too many recursion times, which is also a waste of space. The following describes what is currently called the fastest-bit operation. The principle is not introduced, see here http://blog.csdn.net/xadillax/article/details/6512318

(1) Java code

 

Package com. lin; import java. util. break; /*** n queen problem solving ** @ author lin **/public class QueenTest3 {/** sum is used to record the number of different la s successfully placed by the Queen */public long sum = 0; /** upperlim indicates that all columns have been placed in the Queen */public long upperlim = 1;/*** the test algorithm starts from the rightmost column. * @ Param row vertical column * @ param ld left diagonal line * @ param rd right diagonal line */void queenPos (long row, long ld, long rd) {if (row! = Upperlim) {// row, ld, rd perform the "or" operation to obtain all columns that can be placed in the Queen's status. The corresponding bits are 0, // then retrieve the sum of 1 on the backend and "and" to find all the positions where the current Queen can be placed, change the corresponding column to 1 // determines which columns can be placed in the Queen's long pos = upperlim &~ (Row | ld | rd); while (pos! = 0) // 0 -- the Queen has no place to store, and traces back {// copy the bit with 1 at the rightmost of the pos, set the remaining bit to 0 // that is, obtain the rightmost column of the Queen's long p = pos &-pos; // clear the bits whose rightmost position is 1. // This is used to obtain the rightmost available column of the pos, // In the future, the program will go back to this position to continue testing pos-= p; // row + p, and set the current column to 1, which indicates recording the columns placed by the Queen. // (Ld + p) <1, marking the adjacent columns on the left of the current queen cannot be placed by the next queen. // (Ld + p)> 1. The column adjacent to the right of the current queen cannot be placed by the next queen. // The shift operation here is actually the limit on the diagonal line of the record. It is only because the problem is resolved to the/row mesh, so the column restriction is enough. Obviously, with the shift // performed before each selected column, in the original N × N mesh, a placed Queen's limitations on its diagonal line // were recorded by queenPos (row + p, (ld + p) <1, (rd + p)> 1) ;}} all bits of else {// row are 1, that is, a successful layout is found, backtracking sum ++ ;}} /*** calculate * @ param n queen data */void queen (int queenNum) {if (queenNum <1) | (queenNum> 32) {System. out. println (only between 1-32 values can be calculated); return;} // N queens only need to be stored in N bits. If a column in N has a queen, the corresponding bit is set to 1. Upperlim = (upperlim <queenNum)-1; queenPos (0, 0, 0);} public static void main (String [] args) {queue SC = new Queue (System. in); System. out. print (enter the Queen number); int num = SC. nextInt (); long starTime = System. currentTimeMillis (); // program start time: QueenTest3 queenTest3 = new QueenTest3 (); queenTest3.queen (num); System. out. println (total number of solutions: + queenTest3.sum); long endTime = System. currentTimeMillis (); // end time of the program double runTimes = (double) (endTime-starTime)/1000.0; System. out. println (total program running time: + runTimes + s );}}
Running result:

 

Queen eight's results: (bit operation Version)

Remove the output result from the above Code: (non-bit version)

 

// Print the location of the Resolution queen in sequence/* for (int m = 1; m <= queenNum; m ++) {// System. out. println (x [m]); // This row is output when it is recursive to the leaf node, A feasible solution // write the following for (int k = 1; k <= queenNum; k ++) {if (k = x [m]) only for good looks. {System. out. print (x [m] +);} else {System. out. print (*); // use * to indicate the location that is not used} System. out. println ();} System. out. println ();*/

The output is as follows:

 

After comparison, it is found that the speed is 2 ms

The ten queens effect was not expected to be faster than the eight queens bit operation version (the ten queens bit operation version)

10 Queen's non-bit computing version
10 times faster !!!!!!!!!!!!!!!!!!!

12 queens

Bitwise operation

Non-bitwise operations

(2) C ++ version

 

/*** The fastest method to solve the N queen's recursion at present ** N Queens Problem ** test-backtracing algorithm to implement recursion */# include
      
       
Using namespace std; # include
       
        
// Sum is used to record the number of different la s that have been successfully placed by the Queen; upperlim is used to mark that all columns have been placed by the Queen. Long sum = 0, upperlim = 1; // The test algorithm starts from the rightmost column. Void test (long row, long ld, long rd) {if (row! = Upperlim) {// row, ld, rd perform the "or" operation to obtain all columns that can be placed in the Queen's status. The corresponding bits are 0, // then retrieve the sum of 1 on the backend and "and" to find all the positions where the current Queen can be placed, change the corresponding column to 1 // determines which columns can be placed in the Queen's long pos = upperlim &~ (Row | ld | rd); while (pos) // 0 -- the Queen has no place to store, backtracking {// copy the bit with 1 on the rightmost side of the pos, set the remaining bit to 0 // that is, obtain the rightmost column of the Queen's long p = pos &-pos; // clear the bits whose rightmost position is 1. // This is used to obtain the rightmost available column of the pos, // In the future, the program will go back to this position to continue testing pos-= p; // row + p, and set the current column to 1, which indicates recording the columns placed by the Queen. // (Ld + p) <1, marking the adjacent columns on the left of the current queen cannot be placed by the next queen. // (Ld + p)> 1. The column adjacent to the right of the current queen cannot be placed by the next queen. // The shift operation here is actually the limit on the diagonal line of the record. It is only because the problem is resolved to the/row mesh, so the column restriction is enough. Obviously, with the shift // performed before each selected column, in the original N × N mesh, a placed Queen's limitations on its diagonal line // were recorded as test (row + p, (ld + p) <1, (rd + p)> 1) ;}} all bits of else {// row are 1, that is, a successful layout is found, backtracking sum ++ ;}} int main () {int num; cout <enter the number of Queens:; cin> num; clock_t start, finish; double totaltime; // computing program running time start = clock (); // start time // The maximum length is 32 bits due to integer limitation. // if you want to solve the Queen Problem with N greater than 32, you need to // use the bitset data structure for storage if (num <1) | (num> 32) {cout <can only calculate between 1-32; return 0 ;} // N The Queen only needs N-bit storage. If a column in the N column has a queen, the bit is set to 1. Upperlim = (upperlim <num)-1; test (0, 0, 0); cout <total scheme <sum; finish = clock (); // End Time totaltime = (double) (finish-start)/CLOCKS_PER_SEC; cout <the running time of this program is <
        
         
Output result:
         

 

The following compares the effects of java and C ++ operations:

16 Queen C ++ version (bit operation)

16 Queen's java version (bitwise Operation)

Java is faster.

 

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.