zoukankan      html  css  js  c++  java
  • 回溯与分支定界

    一、一般回溯法

    描述

    •假定算法已经找到部分解为(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两信息,即可拿某个阶段的边界值和目前求得的最佳解值比较:

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

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

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

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

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

     
  • 相关阅读:
    堆的实现(图片演示+文字讲解)
    数据结构之堆的插入、取值、排序(细致讲解+图片演示)
    插入排序
    (简单易懂)Java的快速失败(fail-fast)与安全失败,源码分析+详细讲解
    Eclipse安装Hibernate插件快速生成配置文件
    Hibernate级联操作解密(inverse和cascade)
    http协议详解
    javaweb中的关于编码问题总结
    Hyperparameter tuning
    win10修改jupyter notebook默认路径
  • 原文地址:https://www.cnblogs.com/z-sm/p/5044456.html
Copyright © 2011-2022 走看看