Analysis of backtracking from the eight queens problem

First, let us look at what is the eight queens problem
to place eight queens on the chessboard 8 * 8 without attacking each other (ie any row in the board, and any one of any two queens can not be placed on a diagonal)
Here Insert Picture Description

This question is the use of backtracking algorithm, then what is backtracking algorithm?

Simply put, the first tentative forward in accordance with a method, this method is not found when the optimal solution or can not reach the target, step back , replaced a way to continue to test, know where to find the end date

In fact backtracking algorithm has a very similar routine

void go(int k)
{
    for(i=1;i<=k;i++)
    {
  	if(符合条件)
  	{
  		 ……
   		if(到达终点) {}
   		else go(k+1);
   		//进行回溯
   		返回一步 …… 
  	} 
    }
} 

Then the eight queens problem is the same reason
, such as
Here Insert Picture Descriptionfirst in the (1,1) placed first Queen
then placed into the second line of the second Queen
first enter the (2,1), found that the first conflict, right, arrive (2,2) also found that the first conflict, continue to the right, reach (2,3), there is no conflict, so the second successful occupation of the Queen
Here Insert Picture Description

The third process Queen occupied the same token, the first to reach (3,1), found (1,1) conflict, right, reach (3,2) found (2,3) conflict, right, arrive ( 3,3) and (2,3) conflict, right, reach (3,4), and (2,3) conflict, right, reach (3,5), there is no conflict, the successful occupation

Here Insert Picture Description
So how do you reflect back it?
Like the figure below
Here Insert Picture Description

At this point we have completed seven before filling the Queen, but found that no matter which of the eight queens will be in conflict with other queens, then we step back, the first seven Queens change places, continue to the right, on the ( 7,7) with a fourth Queen conflict, (7,8) and a second Queen's conflicts, this 7th position Queen has no choice, it would continue to backtrack, moving the first six queens, his right constantly looking for the right location

This is the back
so specifically, how to deal with this problem then eight queens

First, we should know that, in order to avoid conflict should not be on the same line, same column, no two queens on the diagonal

Here Insert Picture DescriptionReadily available from the figure, the same elements on the lower right corner of the roadway, the number of lines - is always the same number of columns

The same can be seen, the diagonal elements of the lower left to the number of rows + number of columns is always the same

Then you can generally obtain key codes

Preparing an array queen, she represents the place elements in column j i-th row of the Queen [i] = j;
Flag same column array represents whether the conflict
d1 indicate whether the conflict to the lower right diagonal, +7 here is to allow all the negative numbers They have become non-negative
if (n <8) says that eight queens is not filled, but also need to continue to recursively
otherwise print results

The following print results back only after the end of the step can be run at this time, we need to undo the last step, to seek other results

//判断位置是否冲突 
if((!flag[col])&&(!d1[n-col+7])&&(!d2[n+col]))
  {
   queen[n]=col;//在第n行放置皇后 
   flag[col]=1;//占领col列 
   d1[n-col+7]=1;//占领两个对角线 
   d2[n+col]=1;
   if(n<8)
    display(n+1);//8个皇后没有摆完,就继续递归 
   else
    print();//n=8说明已经排列完成 
   
   //回溯:考虑其他可行方案 
   flag[col]=0;
   d1[n-col+7]=0;
   d2[n+col]=0;  
  }

Attached below the full code

#include<iostream>
using namespace std;

int queen[9]={0};//第i个皇后所在列数 
int flag[9]={0,0,0,0,0,0,0,0,0};//表示第i列是否可占 
int d1[17]={0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};//表示“/”对角线是否可占 
int d2[17]={0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};//表示“\”对角线是否可占
int number=0;//种类数 

void print();//打印函数 
void display(int n);//回溯函数 

int main()
{
	display(1);
	return 0;
}
void display(int n)
{
	int col;
	for(col=1;col<=8;col++)//每种皇后都有8种可能 
	{
		if((!flag[col])&&(!d1[n-col+7])&&(!d2[n+col]))//判断位置是否冲突 
		{
			queen[n]=col;//在第n行放置皇后 
			flag[col]=1;//占领col列 
			d1[n-col+7]=1;//占领两个对角线 
			d2[n+col]=1;
			if(n<8)
				display(n+1);//8个皇后没有摆完,就继续递归 
			else
				print();//n=8说明已经排列完成 
			
			//回溯:考虑其他可行方案 
			flag[col]=0;
			d1[n-col+7]=0;
			d2[n+col]=0;		
		}
	}
}
void print()
{
	int col,i,j;
	number++;
	cout<<"No."<<number<<endl;
	int table[9][9]={0};
	for(col=1;col<=8;col++)
	{
		table[col][queen[col]]=1;
	}
	for(i=1;i<=8;i++)
	{
		for(j=1;j<=8;j++)
		{
			cout<<table[i][j]<<" ";
		}
		cout<<endl;
	}
}

Results are as follows, it was found that 92 possible 8 Queen

Here Insert Picture Description
From this we know, backtracking algorithm is similar to a tentative process of enumeration, when seeking discovery has not satisfied
when the boundary conditions, on the "back" to return to try a different path, to enter into it, you can not then passed back into the

If this article helpful to you, remember to praise focus point oh

Published 37 original articles · won praise 3 · Views 1163

Guess you like

Origin blog.csdn.net/qq_45721778/article/details/105330358