回溯法也称试探法,它的基本思想是:从问题的某一种状态(初始状态)出发,搜索从这种状态出发所能达到的所有“状态”,当一条路走到“尽头”的时候(不能再前进),再后退一步或若干步,从另一种可能“状态”出发,继续搜索,直到所有的“路径”(状态)都试探过。这种不断“前进”、不断“回溯”寻找解的方法,就称作“回溯法”。
用回溯算法解决问题的一般步骤为:
1、定义一个解空间,它包含问题的解。
2、利用适于搜索的方法组织解空间。
3、利用深度优先法搜索解空间。
4、利用限界函数避免移动到不可能产生解的子空间。
问题的解空间通常是在搜索问题的解的过程中动态产生的,这是回溯算法的一个重要特性。
通常情况下,回溯法是通过递归来实现的,所以需要考虑递归的终止条件。同时当我们一条路走到“尽头”的时候,要后退到上一步,同时要消除当前这一步所产生的影响(一般是某些状态值,这是回溯的重点)。
问题描述:
八皇后问题是一个以国际象棋为背景的问题:如何能够在 8×8 的国际象棋棋盘上放置八个皇后,使得任何一个皇后都无法直接吃掉其他的皇后?为了达到此目的,任两个皇后都不能处于同一条横行、纵行或斜线上。
(2)如果检查了该行所有的位置均不能放置一个皇后,说明上一行皇后放置的位置无法让所有的皇后找到自己合适的位置,因此就要回溯到上一行,重新检查该皇后位置后面的位置。
#include <iostream> #include <fstream> using namespace std; int count=0; void solve (int linenum,int *LineSet,bool *column,bool *oblique1,bool *xie2,ofstream &os) { for(int i=0;i<8;i++) { if(!column[i]&&!oblique1[linenum+i]&&!xie2[linenum-i+7]) { LineSet[linenum]=i; column[i]=true; oblique1[linenum+i]=true; xie2[linenum-i+7]=true; if(linenum==7) { for(int k=0;k<8;k++) { for(int j=0;j<8;j++) { if(j==LineSet[k]) { os<<" Q"; }else { os<<" +"; } } os<<endl; } count++; os<<"这是第"<<count<<"种结果"<<endl; os<<endl; LineSet[linenum]=999; column[i]=false; oblique1[linenum+i]=false; xie2[linenum-i+7]=false; return; } else { solve(linenum+1,LineSet,column,oblique1,xie2,os); LineSet[linenum]=999; column[i]=false; oblique1[linenum+i]=false; xie2[linenum-i+7]=false; } } } } int main() { int LineSet[8]; bool column[8]; bool oblique1[15]; bool oblique2[15]; for(int i=0;i<8;i++) { LineSet[i]=999; column[i]=false; } for(int i=0;i<15;i++) { oblique1[i]=false; oblique2[i]=false; } ofstream os("result.txt"); solve(0,LineSet,column,oblique1,oblique2,os); }
结果():
Q + + + + + + +
+ + + + Q + + +
+ + + + + + + Q
+ + + + + Q + +
+ + Q + + + + +
+ + + + + + Q +
+ Q + + + + + +
+ + + Q + + + +
这是第1种结果
Q + + + + + + +
+ + + + + Q + +
+ + + + + + + Q
+ + Q + + + + +
+ + + + + + Q +
+ + + Q + + + +
+ Q + + + + + +
+ + + + Q + + +
这是第2种结果
Q + + + + + + +
+ + + + + + Q +
+ + + Q + + + +
+ + + + + Q + +
+ + + + + + + Q
+ Q + + + + + +
+ + + + Q + + +
+ + Q + + + + +
这是第3种结果
Q + + + + + + +
+ + + + + + Q +
+ + + + Q + + +
+ + + + + + + Q
+ Q + + + + + +
+ + + Q + + + +
+ + + + + Q + +
+ + Q + + + + +
这是第4种结果
+ Q + + + + + +
+ + + Q + + + +
+ + + + + Q + +
+ + + + + + + Q
+ + Q + + + + +
Q + + + + + + +
+ + + + + + Q +
+ + + + Q + + +
这是第5种结果
...
+ + + + + + + Q
+ Q + + + + + +
+ + + + Q + + +
+ + Q + + + + +
Q + + + + + + +
+ + + + + + Q +
+ + + Q + + + +
+ + + + + Q + +
这是第90种结果
+ + + + + + + Q
+ + Q + + + + +
Q + + + + + + +
+ + + + + Q + +
+ Q + + + + + +
+ + + + Q + + +
+ + + + + + Q +
+ + + Q + + + +
这是第91种结果
+ + + + + + + Q
+ + + Q + + + +
Q + + + + + + +
+ + Q + + + + +
+ + + + + Q + +
+ Q + + + + + +
+ + + + + + Q +
+ + + + Q + + +
这是第92种结果
结果比较多,省略了一些,有兴趣可以自己编译运行一下程序代码,查看所有92个解。