回溯与分支定界

一、一般回溯法

描述

•假定算法已经找到部分解为(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[14]。

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两信息,即可拿某个阶段的边界值和目前求得的最佳解值比较:

  如果边界值不能超越(也就是说,在最小化问题中不小于,在最大化问题中不大于)目前的最佳解,这个节点就是一个没有希望的节点,需要立即关闭(剪枝),因为从这个节点生成的解,没有一个能比目前已经得到的解更好。

  这就是分支界限技术的主要思想。

  一般来说,对于一个分支定界算法的状态空间树来说,只要符合下面任一条件,我们就会中止它的在当前节点上的查找路径:

  • 该节点的边界值不优于目前最佳解的值。
  • 该节点无法代表任何可行解, 因为它已经违反了问题的约束。
  • 该节点代表的可行解的子集只包含一个单独的点(因此无法给出更多的选择)。在这种情况下,我们拿这个可行解在目标函数上的值和目前求得的最佳解进行比较,如果新的解更好一些的话,就用前者替换后者。
 

例子:费用限制下的两点最短路

 
原文地址:https://www.cnblogs.com/z-sm/p/5044456.html