一、基本思路
与回溯法一样,分支限界法也是在问题的解空间树上搜索问题的解的一种算法。
二、分支限界法与回溯法的区别
两者很类似,很容易混淆,但有如下显著的区别可区分两者:
1、求解目标不同
回溯法的求解目标一般是找出解空间树中满足条件的所有解。
分支限界法则是尽快找出满足约束条件的一个解,或是在满足约束条件的解中找出在某种意义下的最优解。
2、搜索方式不同
回溯法——>深度优先 遍历结点搜索解空间树。
分支限界法——>广度优先或最小耗费优先搜索解空间树。
3、存储空间不同
分支限界法由于加入了活结点表,所以存储空间比回溯法大得多。因此当内存容量有限时,回溯法的成功率要大一些。
4、扩展结点的方式不同
分支限界法中,每个活结点只有一次机会变成扩展结点,一旦成为扩展结点便一次性生成其所有子结点。
区别小结:回溯法空间效率更高,分支限界法由于只需要求到一个解,所以往往更“快”。
就拿0/1背包问题做例子,回溯法求解0/1背包问题实际上是盲目地搜索解空间树,回溯法只会不断地往下走,虽然通过剪枝函数能减少一定的计算,但是当经过一个结点时,并不知晓其子结点会是怎样的情况,从而盲目继续搜索。而分支限界法则不一样,在经过某一结点时,会根据限界条件判断其结点之下的情况是否能够导出最优解,如若不能,直接不走这条路。这样虽然在空间上不占优势,但是搜索并不盲目,速度上快了很多。
三、求解步骤
1、定义解空间(对解编码)
2、确定解空间树结构(得解空间树)
3、按BFS广度优先方式搜索解空间树:
(1):每个活结点只有一次机会变成扩展结点。
(2):由扩展结点生成一步可达的新结点。
(3):在新结点中删除不可能导出最优解的结点(限界策略,利用限界函数)。
(4):将剩余新结点加入到活结点表中。
(5):在活结点表中再取每个结点(按顺序)进行扩展(分支策略)。
(6):直到活结点表为空。
注:活结点表通常采用堆结构,当求解极大值问题时用大顶堆,极小值问题时用小顶堆。
四、三个重要的函数
1、约束函数:问题定义时需给出的约束条件,如0/1背包问题不能超过其容量。
2、目标函数:是问题要求解的目标函数,分支限界法中需给出一个关于该函数的上下界,方便之后剪枝。
3、限界函数:用于记录当前结点之下可得的最优值,若超出上下界,则可放弃该结点;还用于活结点表中结点排序,限界函数值最优的在第一位,优先扩展遍历。
五、分支限界法的分类
1、队列式分支限界法:在活结点表中,按照FIFO先进先出原则选取下一个结点做扩展结点。
2、优先队列式分支限界法:活结点表中的每个结点对应了一个耗费或收益(其实就是如果扩展该结点,会带来多大的效益),以此决定结点的优先级。
六、经典案例问题
0/1背包问题、单源最短路径问题、最优装载问题。