回溯法与N皇后问题
来源:互联网 发布:认识奢侈品的软件 编辑:程序博客网 时间:2024/06/05 09:03
N皇后问题要求求解在N*N的棋盘上放置N个皇后,并使各皇后彼此不受攻击的可能的棋盘布局,皇后彼此不受攻击的所有可能的布局,皇后彼此不受攻击的约束条件是:任何两个皇后均不能在棋盘同一行、同一列或者在对角线上出现。
由于N皇后问题不允许两个皇后在同一行,所以,可用一维数组X表示N皇后问题的解,X[i]表示第i行的皇后所在的列,条件表述如下:
- X[i] = X[s],则第i行和第s行皇后在同一列上
- 如果第i行的皇后在第j列,第s行的皇后在第t列,即X[i] = j 和 X[s] = t,则只要i - j = s- t 或者 i + j = s + t,说明两个皇后在对角线上,对两个等式进行变换后,得到结论,只要|i- s| = |j - t|(即|i- s| = |x[i] - x[s]|),则皇后在同一对角线上
解N皇后问题需要遍历解空间树,遍历中要随时判定当前棋盘布局是否满足要求,符合要求则继续向下遍历,直至判断得到一个满足约束条件的叶子结点,从而获得一个满足要求的棋盘布局,不符合要求的结点将被舍弃(称之为剪枝),并回溯到上一层的结点继续遍历,当整棵树遍历结束时,已获得所有满足要求的棋盘布局
上面的就是高度为3的解空间树,树的每一层与棋盘的每一行是对应的,首先选择第一行的皇后的位置的时候,是有三个选择的,而这三个选择都是不发生冲突的,因为此时棋盘上还没有任何皇后,当选择第二行的皇后的位置时,对于以上一次选择的为根的子树而言,只有两种选择,而此时就需要判断是否与之前的选择有冲突,如果有冲突的话就需要剪枝(就是说这种方法不符合要求,不必再继续往下尝试了),按照这种方法直至找到满足题意的结果进行输出。
皇后位置满足约束条件的判定如下:
int place(int s) { int i = 1; for(; i < s; i++) { if(abs(i-s) == abs(X[i]-X[s]) || X[i] == X[s]) { return false; } } return true;}
回溯算法:
void Trial(int i, int n) { int j, k; if(i > n) { //输出 for(k = 1; k <= n; k++) { printf("%d ", X[k]); } printf("\n"); } else { for(j = 1; j <= n; j++) { X[i] = j; if(place(i)) { Trial(i+1, n); } } } }
完整代码:
#include<stdio.h>#include<math.h>#include<malloc.h>#define true 1#define false 0void Trial(int i, int n, int *X);int place(int s, int *X);int place(int s, int *X) { int i = 1; for(; i < s; i++) { if(abs(i-s) == abs(X[i]-X[s]) || X[i] == X[s]) { return false; } } return true;} void Trial(int i, int n, int *X) { int j, k; if(i > n) { //输出 for(k = 1; k <= n; k++) { printf("%d ", X[k]); } printf(" \n"); } else { for(j = 1; j <= n; j++) { X[i] = j; if(place(i, X)) { Trial(i+1, n, X); } } } }void main(void) { int n; int *Queen = NULL; printf("请输入皇后的个数.\n"); scanf("%d", &n); Queen = (int *)malloc(sizeof(int) * (n+1)); Trial(1, n, Queen); }
运行结果:
0 0
- N皇后问题与回溯法
- N皇后问题与回溯法
- 回溯法与N皇后问题
- n皇后问题-回溯法
- 【回溯法】n皇后问题
- N皇后问题,回溯法
- 回溯法---n皇后问题
- N皇后问题 【回溯法】
- 【回溯法】n皇后问题
- N皇后问题---回溯法
- N 皇后问题-回溯法
- N皇后问题--回溯法
- 回溯法.N皇后问题
- N皇后问题 回溯法
- 算法分析与设计回溯法之n皇后问题
- 回溯算法与N皇后问题
- 回溯:N皇后问题
- 回溯法解决N皇后问题
- JS:类型转换string 转换成为 number
- Assign Cookies
- const int a; int const a; const int *a; int * const a; int const * const a ; const int * const 之间的区别
- kafka安装配置
- redis 介绍
- 回溯法与N皇后问题
- 【IMWeb训练营作业】select组件
- box-shadow的总结
- Android商品展示实验
- 如何让SQL语句不执行默认排序,而是按照in语句的顺序返回结果
- 日常。。。续
- 商品展示
- DOM Node类
- LeetCode#237. Delete Node in a Linked List