一、一般回溯法
描述
•假定算法已经找到部分解为(x1, x2, …, xj), 然后再考虑向量v=(x1, x2, …, xj ,xj+1), 有下面的情况:
(解向量中每个xi都属于一个有限的线序集Xi)
1.如果v表示问题的最后解,算法记录下它作为一个解,在仅希望获得一个解时终止,或者继续去找出其他解。
2.(向前步骤)。如果v表示一个部分解,算法通过选择集合Xj+2中的第一个元素向前。
3.如果v既不是最终的解,也不是部分解,则有两种子情况。
a.如果从集合Xj+1中还有其他的元素可选择,算法将xj+1置为Xj+1中的下一个元素。
b.(回溯步骤)。如果从集合Xj+1中没有更多的元素可选择,算法通过将xj置为Xj中的下一个元素回溯;如果从集合Xj中仍然没有其他的元素可以选择,算法通过将xj-1置为Xj-1中的下一个元素回溯,依次类推。
递归实现
算法 BACKTRACKREC 输入:集合X1,X2,…, Xn 的清楚的或隐含的描述。 输出:解向量v=(x1, x2, …, xi), i≤n。 v←Φ flag←false backrec(1) if flag then output v else output “no solution” procedure backrec (k) for 每个x∈Xk xk←x; 将xk加入v if v 为最终解then set flag←true and exit else if v 是部分解then backrec (k+1) end for
迭代实现
算法BACKTRACKITER 输入:集合X1,X2,…, Xn 的清楚的或隐含的描述。 输出:解向量v=(x1, x2, …, xi), i≤n。 v←Φ flag←false k←1 while k≥1 while Xk 没有被穷举 xk←Xk 中的下一个元素;将xk加入v if v 为最终解then set flag←true, 且从两个while循环退出 else if v 是部分解then k←k+1 {前进} end while 重置Xk, 使得排在第一位的元素为下一个元素 k←k-1 {回溯} end while if flag then output v else output “no solution”
示例
三着色问题
递归实现: 算法 3-COLORREC 输入:无向图G=(V,E)。 输出:G的顶点的3着色c[1…n], 其中每个c[j]为1,2或3。 for k←1 to n c[k] ←0 end for flag←false graphcolor(1) if flag then output c else output “no solution” Procedure graphcolor(k) for color = 1 to 3 c[k] ←color if c 为原问题的合法解 then flag←true and exit else if c 是部分解 then graphcolor(k + 1) end for 非递归实现: 算法 3-COLORITER 输入:无向图G=(V,E)。 输出:G的顶点的3着色c[1…n], 其中每个c[j]为1,2或3。 for k←1 to n c[k] ←0 end for flag←false k←1 while k≥1 //点、层、分量 while c[k] ≤2 //色、分量取值 c[k] ←c[k]+1 if c 为原问题的合法解 then flag←true ;从两个while 循环退出 else if c 是部分解 then k←k + 1 {前进} end while c[k] ← 0 k←k-1 {回溯} end while if flag then oupput c else output “no solution
四皇后问题
算法 4-QUEENS 输入:空。 输出:对应于4皇后问题的解的向量x[1…4]。 1 for k←1 to 4 2 x[k] ←0 {棋盘上无皇后} 3 end for 4 flag←false 5 k←1 6 while k≥1 7 while x [k] ≤3 8 x [k] ←x [k]+1 9 if x 为原问题的合法解 then flag←true 且从两个while 循环退出 10 else if x 是部分解 then k←k + 1 {前进} 11 end while 12 x [k] ←0 13 k←k-1 {回溯} 14 end while 15 if flag then oupput x else output “no solution”
二、分支定界
•最优化问题是根据某些约束寻求目标函数的最大或最小值。
•可以利用回溯的思想。
•且回溯的思想得到进一步的强化。
•和回溯法相比,分支定界法需要两个额外的条件:
1. 对于一棵状态空间树的每一个节点所代表的部分解,我们要提供一种方法,计算出通过这个部分解繁衍出的任何解在目标函数上的最佳值边界。
2. 目前求得的最佳解的值。
•若能得到1,2两信息,即可拿某个阶段的边界值和目前求得的最佳解值比较:
如果边界值不能超越(也就是说,在最小化问题中不小于,在最大化问题中不大于)目前的最佳解,这个节点就是一个没有希望的节点,需要立即关闭(剪枝),因为从这个节点生成的解,没有一个能比目前已经得到的解更好。
这就是分支界限技术的主要思想。
一般来说,对于一个分支定界算法的状态空间树来说,只要符合下面任一条件,我们就会中止它的在当前节点上的查找路径:
- 该节点的边界值不优于目前最佳解的值。
- 该节点无法代表任何可行解, 因为它已经违反了问题的约束。
- 该节点代表的可行解的子集只包含一个单独的点(因此无法给出更多的选择)。在这种情况下,我们拿这个可行解在目标函数上的值和目前求得的最佳解进行比较,如果新的解更好一些的话,就用前者替换后者。