N-Queens 2 ways to solve problems and code-java and C + + implementation

Source: Internet
Author: User
Tags bitwise

Lin Bingwen Evankaka original works. Reprint please specify the source Http://blog.csdn.net/evankaka

Abstract: This paper mainly discusses the problem of the N-queen problems of the idea, and the Java and C + + to implement the process, and finally, for the improvement of the algorithm, the use of bit operations.

first, the question throws and the preliminary problem solving thought

Question Description: The eight Queens question is a chess-based question: how can you place eight queens on an 8x8 chess board so that no queen can directly eat the rest of the queen? To achieve this, neither of the two queens can be in the same row, vertical line, or slash.


Conversion rules: In fact, the eight queen problem can be generalized to a more general N Queen placement problem: The size of the board becomes NXN, and the number of Queens becomes N. The problem has a solution when and only if n = 1 or n≥4. Make an array a[n] save the solution, where a[i] means the number of columns in row I of the Empress I (note that the value of I is calculated from 0), the following is a simple rule-to-problem extraction process for the eight Queens problem.


(1) Because all queens cannot be placed in the same column, the array cannot have the same two values.
(2) All Queens cannot be on the diagonal, so how do we detect if two queens are on the same diagonal? We will make the checkerboard into a two-dimensional array, as follows:

Suppose there are two queens placed in (I,J) and (k,l) positions, obviously, when and only when |i-k|=|j-l|, two queens are on the same diagonal.

Ii. Code and results

(1) C + + version

Operating platform: VS2013

Operating system: Windows7

/** * N Queen Problem Resolution * @author Lin * */#include <iostream> #include <cmath> #include <time.h>using namespace std; The number of Queen/** */static int num;/** subscript I denotes the first few lines, X[i] represents the position of the queen of line I, note here 0 rows without */static int *x;/** The number of solutions */static int sum = 0;/** *  Determine where the Queen of K-line can be placed * @param k K represents the K-line, X[k]k represents the position of the Queen on line K * @return Boolean false indicates that the Queen */bool place (int k) {for (int j = 1) cannot be placed here J < K;  J + +) {/* If the Queen placed on the current incoming K-line position and the other Queen a diagonal (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); /** * A row of the Queen position of the row is determined * @param t */void backtrack (int t) {if (T > num)/* If the current row is greater than the number of Queens, the solution is found */{sum+   +;/* the position of the Queen */for (int m = 1; M <= num; m++) {//cout << x[m]; /* This line uses output when recursive to the leaf node, a workable solution *///here only for the sake of good looks to write the following for (int k =1; k <= num;k++) {if (k = = X[m]) {cout << x[m] << ""; }else {cout << "*";//use * to indicate a location not used}}cout << Endl;} cout << Endl;}   else {for (int i = 1; I <= num; i++) {x[t] = i;    /* t line Jyoko is placed in the I column */if (place (t)) {/* Here the place function is used to judge the condition we said above, if it is established, enter the next level of recursion */backtrack (T + 1);}}} int main () {cout<< "Please enter Queen number:";cin>>num; clock_t start,finish;double totaltime;//Calculate program run time Start=clock ();//     Start time x= new Int[num + 1];                 /* Note here plus 1, where 0 rows are not used, 1-num respectively corresponds to 1-num line */for (int i = 0; I <= num; i++) x[i] = 0;backtrack (1); /* Incoming first Queen, start recursive */cout << "scheme Total" << sum;delete[]x;finish=clock ();//End Time Totaltime= (double) (Finish-start)/ clocks_per_sec;cout<< "\ n This program runs for" <<totaltime<< "seconds! "<<endl;while (1); return (0);}

Output Result:

8 Queen:


10 Queen:



(2) Java version

Operating platform: Eclispse Luna

Operating system: Windows7


Package Com.lin;import java.lang.*;/** * N Queen Problem Resolution * @author Lin * */public class Queentest {/** subscript I for the first few lines, X[i] represents the position of the queen of line I, note here 0 rows without */public int[] x;/** the number of Queens */public int queennum;/** The number of solutions */public int methodnum; queentest (int queennum) {this.queennum = Queennum;this.x = new int[queennum+1];//Note, here we start with the 1th line, the No. 0 line does not have backtrack (1);//    Starting from the first Queen recursion}/** * A row of the Queen position of the row is determined * @param t */public void backtrack (int t) {if (T > Queennum)//If the current row is greater than the number of Queens, indicates that the solution is found {Methodnum++;//sum for all feasible solutions//print this solution to the Queen's position for (int m = 1; M <= queennum; m++) {//system.out.pri Ntln (X[m]);//This line with the output when recursive to the leaf node, a feasible solution//Here only for the sake of good looks to write the following for (int k =1; k <= queennum;k++) {if (k = = X[m])            {System.out.print (x[m]+ "");        }else {System.out.print ("*");//use * to indicate a location 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)) {//Here is used to judge the condition above, if it is established, enter the next level of recursion, that is, the next queen backtrack (t+1);     }}}}/** * Determine where the Queen of K-line can be placed * @param k K means the K-line, X[k]k represents the position of the Queen on line K * @return Boolean false means the Queen cannot be placed here */public Boolean place (int k) {for (int j = 1; j < K; J + +)//If the Queen placed on the current incoming K-line position and the other Queen a diagonal (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 coefficient:" + queentest.methodnum);}}

Output Result:

This is the eight queens.


This is the Ten Queens:
by comparing Java and C + + discovery, Java runs more quickly. What is this for? The reason is that the new operation is used in C + +, and the basic data in Java is created on the stack and accessed much faster than the heap. third, more efficient algorithm-bit operation version

The above method recursion number is too much, also wasted space, the following describes the currently known as the fastest-bit operation. The principle is not introduced, look here http://blog.csdn.net/xadillax/article/details/6512318

(1) Java code

Package Com.lin;import java.util.scanner;/** * N Queen Problem Resolution * @author Lin * */public class QueenTest3 {/**sum used to record the number of different layouts of Queen placement Success */        public long sum = 0;/**upperlim is used to mark all columns have been placed the Queen */public long Upperlim = 1;   /** * Heuristic algorithm starts from the rightmost column. * @param row Vertical column * @param ld left Diagonal * @param rd Right Diagonal */void queenpos (long row, long ld, Long Rd) {if (Row! = Upperli m) {//Row,ld,rd for "or" operation, to find all the columns that can place the queen, the corresponding bit is 0,//and then after the "and" on the full 1 number, to obtain the current all can place the Queen position, the corresponding column to 1//           That is, what columns are currently available to place Queen long pos = Upperlim & ~ (Row | ld | rd);               while (pos! = 0)//0--Queens have no place to put, backtrack {//copy Pos to the right of the 1 bit, the rest bit 0//To get the rightmost column that can put the Queen                                                              Long p = pos &-pos;                                           To the right of POS 1 bit clear 0//is to get the next most right available column use to prepare,//program will go back to this position in the future to test pos-= p;              Row + p, which puts the current column at 1, indicates that the column the Queen has placed is recorded. (LD + P) << 1, mark the current emperorThe next left side of the column is not allowed to be placed.              (LD + P) >> 1, mark the current Queen right adjacent column does not allow the next queen to be placed. The shift operation here is actually the limit on the diagonal of the record, just because the problem is resolved on a grid-by-line, so the limit is expressed as a column.  Obviously, as the shift//is made before each column is selected, the limit that a placed Queen in the NxN grid has on its diagonal//is recorded queenpos (row + p, (LD                                        + p) << 1, (rd + P) >> 1);      }} else {//row all bits are 1, that is, found a successful layout, backtracking sum++; }/** * Based on the number of Queens passed in * @param n Queen data */void Queen (int queennum) {if (Queennum < 1) | | (Queennum > 32)) {System.out.println ("can only calculate between 1-32 \ n"); return;} n the Queen only needs n-bit storage, and a column in n column has a queen in the corresponding bit 1. Upperlim = (Upperlim << queennum)-1;queenpos (0, 0, 0);}  public static void Main (string[] args) {Scanner sc=new Scanner (system.in);  System.out.print ("Please enter the number of Queens:");  int Num=sc.nextint (); Long Startime=system.currenttimemillis ();//program start time QueenTest3 queenTest3 = new QueenTest3 (); Queentest3.queen (num); System.out.println ("Total coefficient:" + queentest3.sum); long ENdtime=system.currenttimemillis ();//program End time Double runtimes= (double) (endtime-startime)/1000.0; SYSTEM.OUT.PRINTLN ("Program Total elapsed time:" + runtimes + "s");}}
Operation Result:

The effect of the eight Queens: (bit op version)

Remove the output from the above code: (Non-bitwise OP version)

    Print this solution to the Queen's position      */for  (int m = 1; M <= queennum; m++) {           //system.out.println (x[m]);//This line uses output when recursive to the leaf node, A workable solution           //Here is only for the sake of good looks to write the following for           (int k =1; k <= queennum;k++) {           if (k = = X[m]) {         System.out.print (x[m]+ "");            }else {         System.out.print ("*");//use * to indicate a location not used}           }        System.out.println ();        }        SYSTEM.OUT.PRINTLN (); */

Then the output is as follows:


After the comparison, we found that the 2ms was fast.

Ten Queen effect, unexpectedly rather than eight Queen's bit OP version also faster (10 Queen bit op version)


Ten Queens Non-bitwise OP version
10 times times faster,!!!!!!!!!!!!!!!!!!!.

12 Queens

Bit arithmetic


Non-bitwise operations


(2) C + + version

/* * Current fastest N-Queen recursive solution * * N Queens Problem * * heuristic-backtracking algorithm, recursive implementation */#include <iostream>using namespace std;  #include <time.h>//sum is used to record the number of different layouts for the Queen's placement success; Upperlim is used to mark all the columns that have been placed on the Queen.       Long sum = 0, Upperlim = 1;  The heuristic algorithm starts at the rightmost column. void test (long row, long ld, Long Rd) {if (row! = Upperlim) {///Row,ld,rd for "or" operations, all columns that can be placed in Queens, corresponding bits 0,//and then reversed "with" on full   1 of the number, to find the current all can place the Queen's position, the corresponding column to 1//is the current column to find which can be placed Queen long pos = Upperlim & ~ (Row | ld | rd);                                                while (POS)//0--The Queen has no place to put, backtrack {//copy Pos to the right of 1 bit, the rest bit 0//That is to get the rightmost column can put Queen long P = pos &-pos;                             To the right of POS 1 bit clear 0//is to get the next most right available column use to prepare,//program will go back to this position in the future to test pos-= p;  Row + p, which puts the current column at 1, indicates that the column the Queen has placed is recorded.  (LD + P) << 1, mark the current queen left adjacent column does not allow the next queen to be placed.  (LD + P) >> 1, mark the current Queen right adjacent column does not allow the next queen to be placed. The shift operation here is actually the limit on the diagonal of the record, just because the problem is resolved on a grid-by-line, so the limit is expressed as a column. Obviously, as the shift//is made before each column is selected, the limit that a placed Queen in the NxN grid has on its diagonal//is recorded in test (row + p, (ld + p) <&lT                                1, (rd + P) >> 1);  }} else {//row all bits are 1, that is, found a successful layout, backtracking sum++; }} int main () {int num;cout<< "Please enter Queen number:";cin>>num; clock_t start,finish;double totaltime;//Calculate program run time start= Clock ();//start time//due to the limit of the integer number, the maximum can only be 32 bits,//If you want to handle the queen problem of n greater than 32, need//////with BITSET data structure for storage if (num < 1) | |                   (num > 32))  {cout << "can only calculate between 1-32 \ n";  return 0;}  n the Queen only needs n-bit storage, and a column in n column has a queen in the corresponding bit 1.           Upperlim = (upperlim << num)-1;  Test (0, 0, 0); cout << "scheme Total" << sum;finish=clock ();//End Time Totaltime= (double) (Finish-start)/clocks_per_sec;cout< < "\ n This program runs for" <<totaltime<< "seconds!  "<<endl;while (1); return 0; }

Output Result:




Here's a comparison of the effects of Java and C + + operations:

16 Queen C + + version (bitwise operation)


16 Queen Java version (bitwise operation)


It's also a bit faster to find Java.

Copyright NOTICE: This article for Bo Master Lin Bingwen Evankaka original article, reproduced please indicate the source Http://blog.csdn.net/evankaka

N-Queens 2 ways to solve problems and code-java and C + + implementation

Related Article

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.