回溯法:八皇后问题
2015-05-17 12:24
253 查看
八皇后问题是一个以国际象棋为背景的问题:如何能够在 8×8 的国际象棋棋盘上放置八个皇后,使得任何一个皇后都无法直接吃掉其他的皇后?为了达到此目的,任两个皇后都不能处于同一条横行、纵行或斜线上。八皇后问题可以推广为更一般的n皇后摆放问题:这时棋盘的大小变为n×n,而皇后个数也变成n。当且仅当 n = 1 或 n ≥ 4 时问题有解。
这个问题简化描述就是:在8x8的棋盘上放8颗子,要求它们【不在同一行】【不在同一列】【不在同一斜线】上。
我们可以定义一个数组position[8],positon[i]=j代表第i行摆在第j列。所以我们的约束条件可以进行如下表示:
1. 不在同一列:position[i] ≠ position[j]
2. 不在同一主对角线:position[i] - i ≠ position[j] - j
3. 不在同一副对角线:position[i] + i ≠ position[j] + j
其中2和3可以合并成abs(i - j) ≠ abs(position[i] - position[j])
求解思路:
首先从第一个皇后开始,从第一行确定第一个皇后位置,然后再在第二行搜索第二个 皇后位置……没前进一步检查是否满足约束条件,不满足的时候回溯到上一个皇后位置,尝试该行的其他列是否满足条件,直到找到问题的解。
C++参考代码:
总共有92种摆法:
![](https://img-blog.csdn.net/20150517122212430)
下面官方的说一下回溯法(摘自百度百科)。
回溯法(探索与回溯法)是一种选优搜索法,又称为试探法,按选优条件向前搜索,以达到目标。但当探索到某一步时,发现原先选择并不优或达不到目标,就退回一步重新选择,这种走不通就退回再走的技术为回溯法,而满足回溯条件的某个状态的点称为“回溯点”。
基本思想:
在包含问题的所有解的解空间树中,按照深度优先搜索的策略,从根结点出发深度探索解空间树。当探索到某一结点时,要先判断该结点是否包含问题的解,如果包含,就从该结点出发继续探索下去,如果该结点不包含问题的解,则逐层向其祖先结点回溯。(其实回溯法就是对隐式图的深度优先搜索算法)。 若用回溯法求问题的所有解时,要回溯到根,且根结点的所有可行的子树都要已被搜索遍才结束。 而若使用回溯法求任一个解时,只要搜索到问题的一个解就可以结束
这个问题简化描述就是:在8x8的棋盘上放8颗子,要求它们【不在同一行】【不在同一列】【不在同一斜线】上。
我们可以定义一个数组position[8],positon[i]=j代表第i行摆在第j列。所以我们的约束条件可以进行如下表示:
1. 不在同一列:position[i] ≠ position[j]
2. 不在同一主对角线:position[i] - i ≠ position[j] - j
3. 不在同一副对角线:position[i] + i ≠ position[j] + j
其中2和3可以合并成abs(i - j) ≠ abs(position[i] - position[j])
求解思路:
首先从第一个皇后开始,从第一行确定第一个皇后位置,然后再在第二行搜索第二个 皇后位置……没前进一步检查是否满足约束条件,不满足的时候回溯到上一个皇后位置,尝试该行的其他列是否满足条件,直到找到问题的解。
C++参考代码:
#include <iostream> using namespace std; const int N = 8;//皇后的个数 int positon ;//存放皇后的位置 int count = 0;//记录有多少种摆法 /*判断第row行放置的位置是否满足要求*/ bool valid(int row) { for (int i = 0; i < row; ++i) { // 如果和前面放好位置的不在同一列,也不在对角线上,则返回true,否则返回false if (positon[i] == positon[row] || abs(positon[i] - positon[row]) == abs(i - row)) return false; } return true; } /*输出摆放结果*/ void print() { cout << "这是第" << ++count << "种摆法:" << '\n'; for (int i = 0; i < N; ++i) { for (int j = 0; j < N; ++j) { if (positon[i] == j) cout << "⊙ "; else cout << "× "; } cout << '\n'; } cout << endl; } /*回溯法搜索摆放位置*/ void trail(int row = 0) { // 如果摆完完N行,则输出结果 if (N == row) { print(); return; } for (int column = 0; column < N; ++column) { positon[row] = column;// 放置在第row行第column列 // 如果满足条件,则进行下一行 if (valid(row)) trail(row + 1); // 如果不满足条件,则进行下一次循环,即回溯回去在第row行重新寻找摆放的位置 } } int main() { trail(); return 0; }
总共有92种摆法:
下面官方的说一下回溯法(摘自百度百科)。
回溯法(探索与回溯法)是一种选优搜索法,又称为试探法,按选优条件向前搜索,以达到目标。但当探索到某一步时,发现原先选择并不优或达不到目标,就退回一步重新选择,这种走不通就退回再走的技术为回溯法,而满足回溯条件的某个状态的点称为“回溯点”。
基本思想:
在包含问题的所有解的解空间树中,按照深度优先搜索的策略,从根结点出发深度探索解空间树。当探索到某一结点时,要先判断该结点是否包含问题的解,如果包含,就从该结点出发继续探索下去,如果该结点不包含问题的解,则逐层向其祖先结点回溯。(其实回溯法就是对隐式图的深度优先搜索算法)。 若用回溯法求问题的所有解时,要回溯到根,且根结点的所有可行的子树都要已被搜索遍才结束。 而若使用回溯法求任一个解时,只要搜索到问题的一个解就可以结束
相关文章推荐
- 算法[回溯]-八皇后问题
- 八皇后问题——回溯深搜
- 回溯递归算法----八皇后问题
- 从经典的八皇后问题看回溯
- 回溯法求八皇后问题
- 回溯算法思想与八皇后问题解的个数
- 回溯算法--八皇后问题
- 回溯法解八皇后问题及再看八皇后问题优化
- 八皇后问题 C#版本算法 回溯法
- 回溯法解决八皇后和0,1背包问题和排列问题
- 八皇后问题(DFS加回溯)输出排列的所有情况
- uva 11553 Grid Game (回溯- 类似,比八皇后问题简单)
- 八皇后问题 --回溯
- 回溯法:八皇后问题
- 八皇后问题回溯求解
- 回溯问题+幂集、排列、子集和问题、八皇后问题
- 回溯法解八皇后问题
- 从八皇后问题体会回溯法
- Dfs回溯-八皇后问题
- 人工智能MATLAB实现回溯八皇后问题