算法设计与分析复习--回溯法

算法设计与分析期末复习

主要参考:

算法设计与分析(北京航空航天大学MOOC)

算法设计与分析(北京大学MOOC)

​ 华中科技大学 计算机科学与技术学院 算法设计与分析 课堂教学PPT

五、回溯法

回溯算法的例子:4后问题、0-1背包问题、货郎问题

解的形式:向量

搜索空间:树,可能是n叉树,子集树、排列树等等,输的节点对应与部分向量,可行解在叶节点

搜索方法:深度优先,宽度有限,…,跳跃式遍历搜索树,找到解

约束条件、回溯判定

可用回溯法求解的问题:

问题的解可以用一个n元组(x1,…,xn)来表示,其中的xi取自于某个有穷集Si,并且这些解必须使得某一规范函数P(x1,…,xn)取极值或满足该规范函数条件

5.1 回溯算法基本思想

(1)适用:求解搜索问题和优化问题

(2)搜索空间:树,结点对应部分解向量,可行解在树叶上

(3)搜索过程:采用系统的方法隐含遍历搜索树

(4)搜索策略:深度优先,宽度优先,函数优先,宽深结合等

(5)结点分支判定条件:

满足约束条件–分支扩张解向量,不满足约束条件–回溯到该结点的父结点

显式约束条件:限定每个xi只能从一个给定的集合上取值

隐式约束条件:xi必须彼此相关的情况

(6)结点状态:动态生成

​ 白结点(尚未访问),灰结点(正在访问该结点为根的子树),黑结点(该结点为根的子树遍历完成)

(7)存储:当前路径

状态空间树:

  • 问题状态(problem state):树中的每一个结点确定所求解问题的一个问题状态。
  • 状态空间(state space):由根结点到其他结点的所有路径则确定了这个问题的状态空间。
  • 解状态(solution states):是这样一些问题状态S,对于这些问题状态,由根到S的那条路径确定了这解空间中的一个元组。
  • 答案状态(answer states):是这样的一些解状态S,对于这些解状态而言,由根到S的这条路径确定了这问题的一个解。
  • 静态树(static trees):树结构与所要解决的问题的实例无关。
  • 动态树(dynamic trees):根据不同的实例而使用不同的树结构。
  • 活结点:自己已经生成而其所有的儿子结点还没有全部生成的结点。
  • E-结点(正在扩展的结点):当前正在生成其儿子结点的活结点。
  • 死结点:不再进一步扩展或者其儿子结点已全部生成的生成结点。

构造状态空间树的两个方法:回溯法、分枝-限界方法

  • 回溯法------当前E-结点R,生成一个新的儿子C,则C就变成一个新的E-结点,对子树C完全检测后,R结点再次成为E-结点
  • 分枝-限界方法------一个E-结点一直保持到变成死结点为止

5.2 回溯算法的适用条件

多米诺性质:

  • 通俗表达:
  • 若x1到xi-1满足,就可以继续向下搜索
  • 若不满足,则x1到xi也不满足,就回溯

在这里插入图片描述
在这里插入图片描述

5.3 回溯算法的设计步骤

(1)定义解向量和每个分量的取值范围

解向量为 <x1,x2,…,xn>

确定xi的取值集合为Xi,i=1,2,…,n

(2)在<x1,x2,…,xk-1>确定如何计算xk取值集合Sk,Sk包含于Xk

(3)确定结点儿子的排列规则

(4)判断是否满足多米诺性质(个人感觉算法实现中华科ppt表述 更为直观)

(5)确定每个结点分支的约束条件

(6)确定搜索策略:深度优先,宽度优先等

(7)确定存储搜索路径的数据结构

5.4 回溯算法的实现一般性描述

递归实现

(北大mooc表述)

  • Sk是xk的取值集合
算法 ReBack(k)
if k>n then <x1,x2,...,xn>是解
else while Sk ≠ 空集 do
	xk <- Sk 中最小值
	Sk <- Sk-{xk}
	计算Sk+1
	ReBack(k+1)

另一种表述(华科ppt表述):

  • (x1, x2, …xi-1)是由根到一个结点的路径

  • T(x1, x2, …xi-1)是所有xi的集合:对于每一个xi , (x1, x2, …xi)是由根到结点xi的路径(也就是根据某一确定的x1到xi-1所得到的xi取值的集合)

  • 限界函数Bi,如果路径(x1, x2, …xi)不可能延伸到一个答案结点,则Bi(x1, x2, …xi)取假值,否则取真值(也就是添加上xi仍可能是答案,则为真,不可能为答案则为假)

procedure RBACKTRACK(k)
	global n,X(1:n)
	for 满足下式的每个X(k)
		X(k) ∈ T(X(1),...,X(k-1)) and B (X(1),...,X(k)) = true do
		if(X(1),...,X(k)) 是一条已抵达答案结点的路径
			then print(X(1),...,X(k)) endif
			call RBACKTRACK(k+1)
	repeat
end RBACKTRACK

迭代实现

Backtrack
输入: n
输出:所有的解
对于 i = 1,2,...,n 确定Xi				//确定初始取值
k <- 1
计算Sk
while Sk ≠ 空集 do 					 //满足约束分支搜索
	xk <- Sk中的最小值,Sk <- Sk-{xk} 
	if k<n then
		k <- k+1 
	else <x1,x2,...,xn>是解
if k>1 then k <- k-1 goto (第7行)		  //回溯

另一种表述:

procedure BACKTRACK(n)
	integer k,n; local X(1:n)
	k <- 1
	while k>0 do
		if 还剩有没检验过的X(k)使得
			X(k) ∈ T(X(1),...,X(k-1)) and B(X(1),...,X(k)) = true
		then
			if(X(1),...,X(k)) 是一条已抵达一答案结点的路径
			then print(X(1),...,X(k)) endif
			k <- k+1
		else
			k <- k-1
		endif
	repeat
end BACKTRACK

5.5 搜索树结点数的估计

Monte Carlo方法

  1. 从根开始,随机选择一条路径,直到不能分支为止,即从x1,x2,…,依次对xi赋值,每个xi的值是从当时的Si中随机选取,直到向量不能扩张为止

  2. 假定搜索树的其他|Si|-1个分支与以上随机选出的路径一样,计数搜索树的点数

  3. 重复步骤1和2,将结点数进行概率平均

(如果没看明白,去北大MOOC里看例子讲解)

  • 目的:估计搜索树真正访问结点数

  • 步骤:

    • 随机抽样,选择一条路径

      用这条路径代替其他路径

      逐层累加树的结点数

    • 多次选择,取结点数的平均值

Monte Carlo
输入:n为皇后数,t为抽样次数
输出:sum,即t次抽样路长平均值
sum <- 0
for i <- 1 to t do		//凑杨次数t
	m <- Estimate(n)	//m为结点数
	sum <- sum + m
sum <- sum / t

一次抽样

  • m为本次取样得到的树节点总数

  • k为层数

  • r2位上层结点数

  • r1位本层结点数

  • r1 = r2*分枝数

  • n为数的层数

  • 从树根向下计算,随机选择,直到树叶

伪代码

Estimate(n)
m <- 1; r2 <- 1; k <- 1		//m为一次估计结点总数
while k ≤ n do
	if Sk = ∅ then return m //不能继续
    r1 <- |Sk|*r2			//r1为扩张后的结点总数
    m <- m+r1				//r2位扩张前的结点总数
    xk <- 随机选择Sk的元素		//随机选择一步
    r2 <- r1
    k <- k+1

左侧红线路径为一次抽样,右侧为扩张后的数(用于估计一次结点个数)

通过多次抽样,取平均值估计搜索树的结点数(Monte Carlo方法)

在这里插入图片描述

5.6 实例伪代码

例1 装载问题

有n个集装箱,需要装上两艘载重分别为c1,c2的轮船,wi为第i个集装箱的重量,且w1+w2+…+wn≤c1+c2,。

问:是否存在一种合理的装载方案把这n个集装箱装上船?如果有,请给出一种方案。

求解思路

  • 输入:W=<w1,w2,…,wn>为集装箱重量,c1和c2为船的最大载重量

  • 算法思想:

    令第一艘船的装入量为W1(让第一艘船装的尽量多)

    1. 用回溯算法求使得c1-W1达到最小的装载方案
    2. 若满足w1+w2+…+wn-W1≤c2,则回答yes,否则回答no

伪代码

算法 Loading(W,c1)
Sort(W);
B <- c1; best <- c1; i <- 1;		//B为当前船1的空隙,best为最优解情况下船1的空隙
while i ≤ n do						//相当于赋值一个初值
	if 装入i后重量不超过c1
	then B <- B-w1 ; x[i] <- 1 ; i <- i+1
	else x[i] <- 0 ; i<- i+1
if B<best then 记录解 best <- B
Backtrack(i);						//注意这里的Backtrace不是递归,只是一个子函数
if i=1 then return 最优解			  //回溯到根节点了
else goto (第3行)

算法 Backtrace(i)
while i>1 and x[i]=0 do
	i<- i-1;
if x[i] = 1							//左子树换到右子树
then x[i] <- 0
	B <- B + wi
	i <- i+1	

时间复杂度 可以达到O(2^n)

例2 n皇后问题

怎么判断是否形成了互相攻击的格局?

是否在同一列,是否在同一条对角线

procedure PLACE(k)						//判断当前X(k)是否可以放置
	global X(1:k); integer i,k			//是否会和前k-1行放置的皇后冲突
	i <- 1
	while i<k do				
		if X(i)=X(k)
			or ABS(X(i)-X(k))=ABS(i-k)
		then return false
		endif
		i <- i+1
	repeat
	return true
end PLACE

procedure NQUEENS(n)
	integer k,n,X(1:n);
	X(1) <- 0; k<-1
	while k>0 do
		X(k) <- X(k)+1						//第一个皇后放置的位置
		while X(k) <= n and not PLACE(k) do
			X(k) <- X(k)+1
		repeat
		if X(k) <= n						//如果可以放置
		then if k=n
			then print(X)
			else k <- k+1;X(k) <- 0			//还没到最后一行,继续下一行
		else k <- k-1;						//如果不能放置
		endif
	repeat
end NQUEENS
例3 子集和数问题

n个数里面存在某些个数的和等于M

元组大小固定

W(k)是按照从小到大的顺序排好序的(对理解伪代码中的剪枝很重要)

限界函数

在这里插入图片描述

伪代码

procedure SUMOFSUB(s,k,r)				//当前和s,当前元素位置k,k之后所有数的和
	global integer M,n; global real W(1:n); global boolean X(1:n)
	real r,s; integer k,j
	X(k) <- 1
	if s+W(k)=M then					//和等于了M,找到结果
		print(X(j),j <- 1 to k)
	else
		if s+W(k)+W(k+1)<=M then		//算上Wk和Wk+1也不够
			call SUMOFSUB(s+W(k),k+1,r-W(k))//那么就算上Wk,继续搜索
		endif
	endif
	if s+r-W(k)>=M and s+W(k+1) <= M	
	then X(k) <- 0
		call SUMOFSUB(s,k+1,r-W(k))
	endif
end SUMOFSUB

伪代码第12行解释:剪枝

如果算上k之后所有的还不够,那就不继续向下搜索了

由于是从小到大排序好的,如果k+1也超过了,那么后面的全都超过了,也不继续搜索

两个条件都满足的条件下才进行继续搜索

  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
计算机算法分析与设计 计算机算法分析与设计(共33张PPT)全文共33页,当前为第1页。 学习目标 掌握算法分析与设计的基本理论 掌握进行算法分析与设计的基本方法(时间、空间复杂度分析,算法正确性的证明) 掌握计算机领域中常用的非数值计算方法,并学会用这些算法解决实际问题 计算机算法分析与设计(共33张PPT)全文共33页,当前为第2页。 课程要求 教学方式:理论(32学时),实践(16学时) 考核方式:考试(80%)+实验作业(20%) 课程学分:3 先修课程:《离散数学》《数据结构》《数值分析》《C语言程序设计》 计算机算法分析与设计(共33张PPT)全文共33页,当前为第3页。 授课教材 选用教材: 《计算机算法基础》(第二版) 余祥宣,崔国华,邹海明 华中科技大学出版社 参考书目: 《算法引论》 张益新,沈雁 国防科技大学出版社 《算法设计与分析》 周培德 机械工业出版社 计算机算法分析与设计(共33张PPT)全文共33页,当前为第4页。 第一章 导引 ---计算机算法分析与设计是面向设计的、处于核心地位的教育课程 ---计算机算法是计算机科学和计算机应用的核心。 1.什么是算法? 2.如何分析算法? 3.如何表示算法? 4.基本数据结构 计算机算法分析与设计(共33张PPT)全文共33页,当前为第5页。 1.什么是算法 算法 数值计算方法(求解数值问题,插值计算、数值积分等) 非数值计算方法(求解非数值问题,主要进行判断比较) 算法笼统的定义:求解一确定类问题的任意一种特殊方法。 非形式描述:算法就是一组有穷的规则,它规定了解决某一特定类型问题的一系列运算。 计算机算法分析与设计(共33张PPT)全文共33页,当前为第6页。 例1 求两个正整数m,n的最大公因子 算法1-1 欧几里得算法 输入:正整数m和n 输出:m和n的最大公因子 第一步:求余数。r m%n 第二步:判断r=0?,若是,终止(n为答案),否则,转第三步。 第三步:互换,m n,n r,返回第一步。 Begin R m%n r=0? Swap(m.n) End N Y 计算机算法分析与设计(共33张PPT)全文共33页,当前为第7页。 例1 求两个正整数最大公因子的一个实例 假设 m=21 和 n=45,求21和45的最大公因子 第一步:r=m%n=21%45=21; 第二步:r 不等于0,转入第三步; 第三步:互换,m=n=45, n=r=21,返回第一步。 第一步:r=m%n=45%21=3; 第二步:r 不等于0,转入第三步; 第三步:互换,m=n=21, n=r=3,返回第一步。 第一步:r=m%n=21%3=0; 第二步:r 等于0,算法结束,3即为21和45的最大公因子。 计算机算法分析与设计(共33张PPT)全文共33页,当前为第8页。 算法的五个重要特性 确定性 每一种运算必须要有确切的定义,无二义性 可行性 运算都是基本运算,原理上能在有限时间内完成 输入 有 1个或多个输入 输出 一个或多个输出 有穷性 在执行了有穷步运算后终止 计算机算法分析与设计(共33张PPT)全文共33页,当前为第9页。 算法的特性 凡是算法,都必须满足以上五条特性。 只满足前四条特性的一组规则不能称之为算法,只能叫做计算过程。 操作系统就是计算过程的一个典型例子。设计操作系统的目的是为了控制作业的运行,当没有作业时,这一计算过程并不终止,而是处于等待状态,一直等到一个新的作业的进入。 计算机算法分析与设计(共33张PPT)全文共33页,当前为第10页。 算法学习的五个内容 如何设计算法 运用一些基本设计策略规划算法 如何表示算法 用恰当的方式表示算法 如何确认算法 算法正确性的证明(算法确认algorithm validation) 如何分析算法 通过时间和空间复杂度的分析,确定算法的优劣 如何测试程序 测试程序是否会产生错误的结果 计算机算法分析与设计(共33张PPT)全文共33页,当前为第11页。 2.如何分析算法 算法分析是对一个算法需要多少计算时间和存储空间作定量的分析。 算法分析步骤: 首先确定使用那些运算以及执行这些运算所用的时间。(运算包括基本数值运算和一些更基本的任意长序列的运算) 其次是要确定出能反映算法在各种情况下工作的数据集。(即要求我们编造出能产生最好、最坏和有代表性情况的数据配置,通过使用这些数据来运行算法,以更了解算法的性能) 计算机算法分析与设计(共33张PPT)全文共33页,当前为第12页。 全面分析一个算法的两个阶段 事前分析(a priori analysis) 求出该算法的一个时间限界函数(一些关于参数的函数) 事前分析只限于每条语句的频率计数(frequency count,该语句的执行次数,与所用的机器无关,且独

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值