回溯法(算法分析与设计)

0.回溯法的算法框架

A.简介

回溯法,又称试探法。一般需要遍历解空间,时间复杂度概况:子集树Ω(2^n),排序树Ω(n!),暴力法

B.回溯法解题三步骤

1)定义问题的解空间

如0-1背包问题,当n=3时,解空间是(0,0,0)、(0,0,1)、(0,1,0)、(0,1,1)、(1,0,0)、(1,0,1)、(1,1,0)、(1,1,1)。1代表选择该物品,0代表不选择该物品

2)确定易搜索的解空间结构

3)以深度优先方式搜索解空间,并在搜索过程中用剪枝函数避免无效搜索

C.子集树、排列树及其他

1)子集树

a.概念

当所给问题是从n个元素的集合S中找出S满足的某种性质的子集时,相应的解空间树称为子集树。例如,0-1背包问题,要求在n个物品的集合S中,选出几个物品,使物品在背包容积C的限制下,总价值最大(即集合S的满足条件<容积C下价值最大>的某个子集)。

另:子集树是从集合S中选出符合限定条件的子集,故每个集合元素只需判断是否(0,1)入选,因此解空间应是一颗满二叉树

b.回溯法搜索子集树的一般算法

void backtrack(int t)//t是当前层数 
{
	if(t>n)//需要判断每一个元素是否加入子集,所以必须达到叶节点,才可以输出
	{
		output(x);
	}
	else
	{
		for(int i=0;i<=1;i++)//子集树是从集合S中,选出符合限定条件的子集,故每个元素判断是(1)否(0)选入即可(二叉树),因此i定义域为{0,1} 
		{
			x[t]=i;//x[]表示是否加入点集,1表示是,0表示否
			if(constraint(t)&&bound(t))//constraint(t)和bound(t)分别是约束条件和限定函数 
			{
				backtrack(t+1);
			}
		}
	}
} 

2)排列树

a.概念

当问题是确定n个元素满足某种性质的排列时,相应的解空间称为排列树。排列树与子集树最大的区别在于,排列树的解包括整个集合S的元素,而子集树的解则只包括符合条件的集合S的子集。

b.回溯法搜素排列树的一般算法


void backtrack(int t)//t是当前层数 
{
	if(t>n)//n是限定最大层数 
	{
		output(x);
	}
	else
	{
		for(int i=t;i<=n;i++)//排列树的节点所含的孩子个数是递减的,第0层节点含num-0个孩子,第1层节点含num-1个孩子,第二层节点含num-2个孩子···第num层节点为叶节点,不含孩子。即第x层的节点含num-x个孩子,因此第t层的i,它的起点为t层数,终点为num,第t层(根节点为空节点,除外),有num-t+1个亲兄弟,需要轮num-t+1回 
		{
			swap(x[t],x[i]);//与第i个兄弟交换位置,排列树一条路径上是没有重复节点的,是集合S全员元素的一个排列,故与兄弟交换位置后就是一个新的排列
			if(constraint(t)&&bound
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值