算法设计技巧与分析(七):回溯(Backtracking)


回溯(Backtracking)

  • 节点以深度优先搜索方式生成;

  • 不需要存储整个搜索树,只需要存储从根节点到当前活动节点的路径。事实上,根本不生成任何物理节点,整棵树都是隐式的。

一、三着色问题(The 3-Coloring Problem)

给定一个无向图G=(V,E),需要用三种颜色中的一种给V中的每个顶点上色,例如1、2和3,这样相邻的两个顶点就没有相同的颜色。我们称这种颜色为合法的;否则,如果两个相邻顶点具有相同的颜色,则为非法的。着色可以用n元组(c1,c2,…,cn)表示,这样ci属于{1, 2, 3}。

所有可能的颜色集都可以用一个称为搜索树的完整三元树来表示。在该树中,从根节点到叶节点的每个路径代表一个着色分配。如果没有两个相邻的着色顶点具有相同的颜色,则图的不完全着色是部分着色。

  • 如果此路径的长度小于n且相应的着色为部分着色,则生成当前节点的一个子节点并将其标记为当前节点。

  • 如果对应的路径不是部分着色的,则当前节点被标记为死节点,并生成对应于另一种颜色的新节点。

  • 如果尝试了所有三种颜色但均未成功,则搜索将返回到颜色已更改的父节点,依此类推。

搜索树的构建如下图所示:

在这里插入图片描述

算法伪代码如下:

递归算法:

Input: 无向图G=(V, E).
Output: G的顶点的3-着色c[1…n],其中每个c[j]123for k = 1 to n:
	c[k] = 0
flag = false//有无解标志
graphcolor(1)
if flag == false:
	return "无解"
else:
	return c

def graphcolor(k):
	for color = 1 to 3:
		c[k] = color;
		if c 合法:
			flag = true
			return
		else if c 部分着色:
			graphcolor(k+1)//若此时k+1点的三个颜色都不符合,自动回溯到k点并继续执行for

迭代算法:

Input: 无向图G=(V, E).
Output: G的顶点的3-着色c[1…n],其中每个c[j]123for k = 1 to n:
	c[k] = 0
k = 1
while 1 <= k <= n :
	while c[k] <= 2:
		c[k] = c[k] + 1;
		if c 合法:
			return true
		else if c 部分着色:
			k++
	//如果三个颜色都不行,则回溯
	c[k] = 0
	k = k - 1
return "无解"

二、八皇后问题(The 8-Queens Problem)

在4X4格的国际象棋上摆放八个皇后,使其不能互相攻击,即任意两个皇后都不能处于同一行、同一列或同一斜线上。

每种可能的配置都可以用四个分量x=(x1、x2、x3、x4)的向量来描述,其中xi表示第i行的皇后所在的列数。由此可以保证每个皇后不在同一行;若xi均不相同,则可以保证每个皇后不在同一列;且仅当: x i − x j = i − j x_i - x_j = i - j xixj=ij x i − x j = j − i x_i - x_j = j - i xixj=ji时,皇后会在同一对角线。

搜索树的构建如下图所示:

在这里插入图片描述

算法伪代码如下:

迭代算法:

Input: none
Output: 对应于4皇后问题解的向量x[14]for k = 1 to 4:
	x[k] = 0
k = 1
while 1 <= k <= 4 :
	while x[k] <= 3:
		x[k] = x[k] + 1;
		if x 合法:
			return true
		else if c 部分放置:
			k++
	//如果四个位置都不行,则回溯
	x[k] = 0
	k = k - 1
return "无解"

三、一般的回溯算法

在这里插入图片描述

四、分支定界(Branch and Bound)

当回溯搜索满足某些属性(包括最大化或最小化)的解或解集时,分枝定界算法通常只关注给定函数的最大化或最小化。此外,在分支定界算法中,在每个节点x上计算节点给出的任何解的可能值的定界,这些解随后可能在以x为根的子树中生成。如果计算的边界比上一个边界差,则以x为根的子树将被阻止扩展。

此后,我们将假设该算法是最小化给定的代价函数;最大化的情况也类似。对于所有部分解(partial solutions )(x1,x2,…,xk-1)及其扩展(x1,x2,…,xk),我们必须满足:
在这里插入图片描述
给定此属性,如果部分解(x1,x2,…,xk)的成本大于或等于先前计算的解,则该部分解(x1,x2,…,xk)在生成后可被丢弃。因此,如果该算法找到一个代价为c的解,并且存在一个代价至少为c的部分解,则不会生成该部分解的更多扩展。

利用分支定界法求解旅行商问题

给定一组城市和在每对城市上定义的成本函数,找到一个最小成本的旅游。在这里,旅游是一条封闭的路径,每座城市只访问一次。成本函数可以是距离、旅行时间、机票等。TSP的一个实例由其成本矩阵给出,其条目假定为非负数。
在这里插入图片描述
对于每个部分解(x1,x2,…,xk),我们关联一个下界y,它是按此顺序访问城市x1,x2,…,xk的任何完整旅行的成本必须至少为y。
我们观察到,每个完整的巡回必须包含成本矩阵中每行和每列的一条边及其相关成本。如果从成本矩阵A的任何行或列中的每个条目中减去常数r,则新矩阵下的任何旅行的成本正好比A下的相同旅行的成本低r。这激发了减少成本矩阵的想法,以便每行或每列至少包含一个等于0的条目。我们将这种矩阵称为原始矩阵的规约化(reduction)。

规约化矩阵如下图所示:

在这里插入图片描述

设(r1,r2,…,rn)和(c1,c2,…,cn)分别为n*n的成本矩阵A中从第1行到第n行和第1列到第n列中减去的金额,定义如下任何完整行程成本的下限y:
在这里插入图片描述
搜索树的构建如下图所示:

在这里插入图片描述

在这里插入图片描述

但此算法不能保证最优解。

  • 0
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
着色回溯算法(Graph Coloring Backtracking Algorithm)是一种经典的求解图的顶点着色问题算法。它的目标是给定一个图,为每个顶点分配一个颜色,并且保证相邻的顶点具有不同的颜色。 在图着色回溯算法中,我们首先选择一个未被着色的顶点,并尝试为其分配一个颜色。然后,继续递归地为其他未被着色的顶点尝试着色,直到所有顶点都得到了合适的颜色或者发现无法将某个顶点着色为任何颜色。如果发现无法为某个顶点找到合适的颜色,则回溯到前一个顶点,尝试其他颜色。这个过程将会重复进行,直到找到所有顶点的合适着色方案。 时间复杂度是一种用来衡量算法性能的指标。对于图着色回溯算法,时间复杂度取决于图的规模、结构以及算法的具体实现。 在最坏情况下,图着色回溯算法的时间复杂度可以达到指数级,即O(2^n),其中n表示图中顶点的个数。这是因为在最坏情况下,每个顶点都需要尝试所有可能的颜色,从而导致了指数级的时间复杂度。 然而,在实际应用中,我们通常可以做一些优化来减少时间复杂度。例如,可以根据某些启发式规则或图的特殊性质来预先选择顶点的颜色,从而缩小搜索空间。这些优化方法可以显著提高算法的效率,降低时间复杂度。 总的来说,图着色回溯算法的时间复杂度在最坏情况下是指数级的,但在实际应用中可以通过一些优化方法来提高效率。对于大规模的图,可能需要考虑其他更高效的算法来解决顶点着色问题

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值