五大算法之(4)回溯

引言

回溯算法也叫试探法,它是一种系统地搜索问题的解的方法。回溯算法的基本思想是:从一条路往前走,能进则进,不能进则退回来,换一条路再试。用回溯算法解决问题的一般步骤为:

1、定义一个解空间,它包含问题的解。

2、利用适于搜索的方法组织解空间。

3、利用深度优先法搜索解空间。

4、利用限界函数避免移动到不可能产生解的子空间。

问题的解空间通常是在搜索问题的解的过程中动态产生的,这是回溯算法的一个重要特性。

基本思想

回溯算法的基本思想是:从一条路往前走,能进则进,不能进则退回来,换一条路再试。

八皇后问题就是回溯算法的典型,第一步按照顺序放一个皇后,然后第二步符合要求放第2个皇后,如果没有位置符合要求,那么就要改变第一个皇后的位置,重新放第2个皇后的位置,直到找到符合条件的位置就可以了。

回溯在迷宫搜索中使用很常见,就是这条路走不通,然后返回前一个路口,继续下一条路。

回溯算法说白了就是穷举法。不过回溯算法使用剪枝函数,剪去一些不可能到达 最终状态(即答案状态)的节点,从而减少状态空间树节点的生成。

回溯法是一个既带有系统性又带有跳跃性的的搜索算法。它在包含问题的所有解的解空间树中,按照深度优先的策略,从根结点出发搜索解空间树。算法搜索至解空间树的任一结点时,总是先判断该结点是否肯定不包含问题的解。如果肯定不包含,则跳过对以该结点为根的子树的系统搜索,逐层向其祖先结点回溯。否则,进入该子树,继续按深度优先的策略进行搜索。回溯法在用来求问题的所有解时,要回溯到根,且根结点的所有子树都已被搜索遍才结束。而回溯法在用来求问题的任一解时,只要搜索到问题的一个解就可以结束。

这种以深度优先的方式系统地搜索问题的解的算法称为回溯法,它适用于解一些组合数较大的问题。

经典示例

1)八皇后问题

#include <stdio.h>
#include <math.h>

int a[9] = {0};
int n = 8, count = 0;

//位置冲突算法
bool Chongtu(int a[], int n)//a[]位置数组,n皇后个数
{
	int i = 0, j = 0;

	for (i = 2; i <= n; ++i)//i:位置
		for (j = 1; j <= i-1; ++j)//j:位置
			if ((a[i] == a[j]) || (abs(a[i]-a[j]) == i-j))//1:在一行;2:在对角线上
				return false;   //冲突
	return true;//不冲突
}

//八皇后问题:回溯算法(递归版)
void Queens8(int k) //参数k:递归摆放第k个皇后
{
	int i = 0;

	if (k > n)      //k>n——即k>8表示最后一个皇后摆放完毕
	{
		printf("第%d种情况:",++count);
		for (i = 1; i <= n; ++i)
			printf("%d ",a[i]);//打印情况
		printf("\n");
	}
	else   //8个皇后未全部摆放完毕
	{
		for (i = 1; i <= n; ++i)//摆放第k个皇后时(注释:转下一行)
		{       //依次从列顶端开始搜索,一直到列底端,直到找到合适位置,如果未找到,自动返回上层递归(回溯)
			a[k] = i;
			if (Chongtu(a,k))//不冲突
				Queens8(k+1);//递归摆放下一个皇后
		}
	}
	return;
}

//主函数
int main()
{
	Queens8(1);//参数1:表示摆放第1个皇后 

	return 0;
}

更详细的八皇后问题说明,可以参考:经典算法——回溯(http://blog.csdn.net/qingdujun/article/details/26282895

(未完待续……)

参考文献:

1)百度百科,回溯算法,http://baike.baidu.com/view/6056523.htm

时间: 2024-11-07 20:01:05

五大算法之(4)回溯的相关文章

五大算法基本思想—分治,动态规划,贪心,回溯,分支界限

一.算法理解 算法是什么,即是按照一定的步骤,一步步去解决某个问题,解决问题的方法步骤就称为算法,例如数学中我们学过的做一个运算,解一个方程,等等,都需要有一个清晰的思路,一步步地去完成.可以说算法就在身边. 算法和计算机有什么关系,计算机它是机器,没有人类的大脑可以思考,但是它怎么完成我们交给他的人物的呢,就是通过算法(当然是人为预先设计好的),计算机解决任何问题都要依赖于算法,没有算法也就没有计算机. 为了计算机能更好更有效率的运行,算法就必须足够好,既要正确易理解,又要可靠效率.下面来研究

五大算法:分治,贪心,动态规划,回溯,分支界定

分治算法 一.基本概念 在计算机科学中,分治法是一种很重要的算法.字面上的解释是"分而治之",就是把一个复杂的问题分成两个或更多的相同或相似的子问题,再把子问题分成更小的子问题--直到最后子问题可以简单的直接求解,原问题的解即子问题的解的合并.这个技巧是很多高效算法的基础,如排序算法(快速排序,归并排序),傅立叶变换(快速傅立叶变换)-- 任何一个可以用计算机求解的问题所需的计算时间都与其规模有关.问题的规模越小,越容易直接求解,解题所需的计算时间也越少.例如,对于n个元素的排序问题,

五大算法

分治算法一.基本概念 在计算机科学中,分治法是一种很重要的算法.字面上的解释是“分而治之”,就是把一个复杂的问题分成两个或更多的相同或相似的子问题,再把子问题分成更小的子问题……直到最后子问题可以简单的直接求解,原问题的解即子问题的解的合并.这个技巧是很多高效算法的基础,如排序算法(快速排序,归并排序),傅立叶变换(快速傅立叶变换)…… 任何一个可以用计算机求解的问题所需的计算时间都与其规模有关.问题的规模越小,越容易直接求解,解题所需的计算时间也越少.例如,对于n个元素的排序问题,当n=1时,

五大算法—分支限界法

分支限界法 一.基本描述 类似于回溯法,也是一种在问题的解空间树T上搜索问题解的算法.但在一般情况下,分支限界法与回溯法的求解目标不同.回溯法的求解目标是找出T中满足约束条件的所有解,而分支限界法的求解目标则是找出满足约束条件的一个解,或是在满足约束条件的解中找出使某一目标函数值达到极大或极小的解,即在某种意义下的最优解. (1)分支搜索算法 所谓“分支”就是采用广度优先的策略,依次搜索E-结点的所有分支,也就是所有相邻结点,抛弃不满足约束条件的结点,其余结点加入活结点表.然后从表中选择一个结点

算法分析中常用的五大算法

分治算法一.基本概念 在计算机科学中,分治法是一种很重要的算法.字面上的解释是“分而治之”,就是把一个复杂的问题分成两个或更多的相同或相似的子问题,再把子问题分成更小的子问题……直到最后子问题可以简单的直接求解,原问题的解即子问题的解的合并.这个技巧是很多高效算法的基础,如排序算法(快速排序,归并排序),傅立叶变换(快速傅立叶变换)…… 任何一个可以用计算机求解的问题所需的计算时间都与其规模有关.问题的规模越小,越容易直接求解,解题所需的计算时间也越少.例如,对于n个元素的排序问题,当n=1时,

8皇后以及N皇后算法探究,回溯算法的JAVA实现,非递归,循环控制及其优化

上两篇博客 8皇后以及N皇后算法探究,回溯算法的JAVA实现,递归方案 8皇后以及N皇后算法探究,回溯算法的JAVA实现,非递归,数据结构“栈”实现 研究了递归方法实现回溯,解决N皇后问题,下面我们来探讨一下非递归方案 实验结果令人还是有些失望,原来非递归方案的性能并不比递归方案性能高 代码如下: package com.newflypig.eightqueen; import java.util.Date; /** * 使用循环控制来实现回溯,解决N皇后 * @author [email pr

五大算法思想—贪心算法

贪心法理解 贪心法在解决问题的策略上目光短浅,只根据当前已有的信息就做出选择,而且一旦做出了选择,不管将来有什么结果,这个选择都不会改变.换言之,贪心法并不是从整体最优考虑,它所做出的选择只是在某种意义上的局部最优. 一句话:不求最优,只求可行解. 判断贪心法 对于一个具体的问题,怎么知道是否可用贪心算法解此问题,以及能否得到问题的最优解? 我们可以根据贪心法的2个重要的性质去证明:贪心选择性质和最优子结构性质. 1.贪心选择性质 什么叫贪心选择?从字义上就是贪心也就是目光短线,贪图眼前利益,在

游戏与常用的五大算法---下篇

前言: 心是一个人的翅膀,心有多大,世界就有多大.很多时候限制我们的,不是周遭的环境,也不是他人的言行,而是我们自己!看不开,放不下,忘不了,把自己囚禁在灰暗的记忆里:不敢想,不自信,不行动,把自己局限在自己的控件里面......如果不能 打破心的桎梏,即使给你整个天空,你也找不到自由地感觉!so fighting! ---------摘自<美文欣赏> PS:为了方便大家阅读,个人认为比较重要的内容-------红色字体显示 个人认为可以了解的内容-------紫色字体显示 ---------

五大算法—分治算法

分治算法 一.基本概念 在计算机科学中,分治法是一种很重要的算法.字面上的解释是“分而治之”,就是把一个复杂的问题分成两个或更多的相同或相似的子问题,再把子问题分成更小的子问题……直到最后子问题可以简单的直接求解,原问题的解即子问题的解的合并.这个技巧是很多高效算法的基础,如排序算法(快速排序,归并排序),傅立叶变换(快速傅立叶变换)…… 任何一个可以用计算机求解的问题所需的计算时间都与其规模有关.问题的规模越小,越容易直接求解,解题所需的计算时间也越少.例如,对于n个元素的排序问题,当n=1时

五大算法—贪心算法

贪心算法 一.基本概念: 所谓贪心算法是指,在对问题求解时,总是做出在当前看来是最好的选择.也就是说,不从整体最优上加以考虑,他所做出的仅是在某种意义上的局部最优解. 贪心算法没有固定的算法框架,算法设计的关键是贪心策略的选择.必须注意的是,贪心算法不是对所有问题都能得到整体最优解,选择的贪心策略必须具备无后效性,即某个状态以后的过程不会影响以前的状态,只与当前状态有关. 所以对所采用的贪心策略一定要仔细分析其是否满足无后效性. 二.贪心算法的基本思路: 1.建立数学模型来描述问题. 2.把求解