算法与数据结构-回溯法及八皇后问题求解
来源:互联网 发布:tomcat是java开发的吗 编辑:程序博客网 时间:2024/05/22 01:52
序言
在笔试中会遇到一些可以用常用算法就能快速解决的问题,如果对这些算法不熟悉的话,在笔试中是比较吃亏的。
这篇文章学习回溯法及用回溯法解决的八皇后问题。
1. 回溯法
基本思想
有时我们要得到问题的解,先从其中某一种情况进行试探,在试探过程中,一旦发现原来的选择是错误的,那么就退回一步重新选择,然后继续向前试探,反复这样的过程直到求出问题的解。
回溯法在用来求问题的任一解时,只要搜索到问题的一个解就可以结束。这种以深度优先的方式系统地搜索问题的解的算法称为回溯法,它适用于解一些组合数较大的问题。
算法步骤
明确问题的解空间:描述解的形式,定义一个解空间,它包含问题的所有解。
构造约束函数/剪枝函数:约束函数是根据题意给出的,通过描述合法解的一般特征用于去除不合法的解,从而避免继续搜索出这个不合法解的剩余部分。
通过DFS思想完成回溯
2. 八皇后问题
问题描述
- 八皇后问题是在8*8的棋盘上放置8枚皇后,使得棋盘中每个纵向、横向、左上至右下斜向、右上至左下斜向均只有一枚皇后。即各个皇后之间不再同一行、不在同一列也不在对角线。
问题求解
采用回溯法求解。从上至下依次在每一行放置皇后,进行搜索,若在某一行的任意一列放置皇后均不能满足要求,则不再向下搜索,而进行回溯,回溯至有其他列可放置皇后的一行,再向下搜索,直到搜索至最后一行,找到可行解,输出。
步骤
1. 构造n × n的数组。数组下标表示皇后所在行、数组元素表示皇后所在列。2. 回溯过程:假设前n-1行的皇后已经按照规则排列好,那么可以使用回溯法逐个试出第n行皇后的合法位置。 所有皇后的初始位置都是第0列,那么逐个尝试就是从0试到N-1,如果达到N,仍未找到合法位置, 回退一行,且该行的皇后的位置加1,继续尝试。如果目前处于第0行,还要再回退,说明此问题已再无解。3. 剪枝函数/约束函数:如果当前行的皇后的位置还是在0到N-1的合法范围内,那么首先要判断该行的皇后是否与前几 行的皇后互相冲突,如果冲突,该行的皇后的位置加1,继续尝试;如果不冲突,判断下一行的皇后。 如果已经是最后一行,说明已经找到一个解,输出这个解。4. 然后最后一行的皇后的位置加1,继续尝试下一个解。
代码(C,递归方式)
#include <stdio.h>#include <stdlib.h>#define bool char#define true 1#define false 0#define N 8void solve(int row);bool valid(int row, int column);void output(void); //输出函数int matrix[N][N] = {{0}}; //棋盘,声明为全局变量简化valid函数参数int counter = 0; //方案计数/* 主函数 */int main(){ BackTrack(1); return 0;}/* 递归函数实现回溯算法 */void BackTrack(int row){ int j; for (j = 0; j < N; j++) { matrix[row - 1][j] = 1; //先在第一列放置皇后 if (valid(row - 1, j)) { if (row == N) output(); //有解,将一直递归至最后一行并输出 else BackTrack(row + 1); } matrix[row - 1][j] = 0; //否则,看当前行下一列 }}/* 剪枝函数:验证第row行第column列放置皇后是否可行 */bool valid(int row, int column){ if (row == 0) return true; //第一行,无条件输出 //不在同一列 int i = 0, j = 0; for (; i < row; i++) { if (matrix[i][column] == 1) return false; } //不在对角线:主对角线和副对角线 i = row - 1; //当前行是row - 1行,上一行row - 2 j = column - (row - i); //对角线:行差 = 列差,即row - 1 - i = column - j while (i >= 0 && j >= 0) { if (matrix[i][j] == 1) return false; i--; j--; } i = row - 1; j = column + (row - i); //对角线:行差 = 列差,即row - 1 - i = j - column while (i >= 0 && j <= 7) { if (matrix[i][j] == 1) return false; i--; j++; } //否则,可行 return true;}/* 可行方案输出 */void output(void){ int i, j; counter++; printf("solution %dth: \n", counter); for (i = 0; i < N; i++) { for (j = 0; j < N; j++) { printf("%d ", matrix[i][j]); } printf("\n"); } printf("\n");}
Acknowledgements:
http://zephiruswt.blog.51cto.com/5193151/895797
http://blog.csdn.net/daniel_ustc/article/details/17040315
http://blog.csdn.net/sinat_33052719/article/details/51447531
2017.09.12
阅读全文
0 0
- 算法与数据结构-回溯法及八皇后问题求解
- 数据结构学习之回溯法求解八皇后问题
- 八皇后问题求解-回溯算法
- 用回溯法求解八皇后问题
- 回溯法求解八皇后问题
- 回溯法求解八皇后问题
- 回溯法求解八皇后问题
- 回溯法求解八皇后问题
- 回溯法求解八皇后问题
- C++数据结构--回溯算法--八皇后问题
- 数据结构与算法中的“递归”——用回溯法求解8皇后问题
- 八皇后问题回溯求解
- 【算法训练】八皇后问题回溯算法求解
- 八皇后问题与回溯算法
- 八皇后问题与回溯算法
- 八皇后及N皇后的回溯与递归算法
- 八皇后及回溯算法
- 经典算法10:回溯法求解八皇后
- mysql千万级大数据SQL查询优化
- 26. Remove Duplicates from Sorted Array
- Java正则表达式爬取网页,贴出完整代码
- JAVA问题研究--基础
- 安卓内存泄漏和内存溢出区别
- 算法与数据结构-回溯法及八皇后问题求解
- Spring详解(五)------AOP
- SIFT算法详解
- 《机器学习实战》朴素贝叶斯
- HDU 4405 Aeroplane chess(概率DP求期望)
- JSONP跨域
- C#基础-046 冒泡排序和选择排序算法
- 关于SQL Server中修改“用户自定义表类型”的问题
- splunk 服务器 +windows&linux forwarder 安装