1.什么是分支限界法?
搜索解空间树:广度优先/最小消费(最大效益)优先
特点:
- 每个活结点只有一次机会成为扩展结点
- 成为扩展结点的活结点一次性产生所有子节点
- 子节点中导致不可行解/非最优解的舍去,其余加入活结点表
- 不断从活结点表中取下一结点进行处理,直到表空/找到所需的结点
取下一结点的方式:
- 队列式
- 优先队列式
2.队列式分支限界法
类似层次遍历,广度优先搜索
3.优先队列式分支限界法
- 优先队列中规定的结点优先级,是与结点相关的数值p
- 实现:最大堆、最小堆
- 上界函数的作用:①剪枝,加速搜索②作为优先级
priority_queue实现:博主_吕白文章
使用优先队列方式:
①节点类:
- 节点编号
- 当前解
- 优先级
- 当前路径,数组记录/添加父结点指针
②算法辅助类:
- 题目提供的数据,如:0-1背包里的物品件数,背包容量,物品的价值和重量
- 算法的过程数据:当前解和当前最优解,当前路径
- 将分支限界算法函数声明为友元函数
- 剪右枝需要的上界函数
③上界函数
- 当前值+剩余可能的最大值
④实现分支限界的函数
- 优先队列 priority_queue<节点类/节点类的指针> Q
- 初始化,currw,bestw,currx,bestx等
- 进入循环求解:是否到达叶子节点;考察左子结点;考察右子结点;取出队首结点(队列不为空时)。
*路径的构造:每个结点用数组记录当前路径,或者每个结点记录自己的前驱节点
*所在的层次:活结点表中每层次的最后加入一个标记的结点/每个结点记录自己所在的层次
4.实例分析
问题 | 解空间 | 结点类 | 算法辅助信息 | 图像 |
---|---|---|---|---|
单源最短路径 | 子集树 | ①优先级:源点到该点的当前最短路径长 ②结点编号 重载< or 仿函数类 | ①图的顶点数n、邻接矩阵G[n][n] ②目前源点到各点的最短路径长dist[n] ③各点路径上的前驱顶点prev[n] | |
0-1背包 | 子集树 | ①优先级:当前价值+剩余物品装入背包的最大价upprofit ②当前价值profit、当前重量weight,所在层次lev ③父结点parent,是否左子结点lchild 重载< or 仿函数类 | ①物品件数n,背包容量c,物品价值v[n],物品重量v[n] ②当前价值cp,当前重量cw,当前最优价值bestp ③最优物品集合bestx[n] ④上界函数Bound(i)求i~n件物品放入c-cw的最大价值+cp | |
电路布线 | 子集树 | 行row列colum | 每一个格子当前到达步数grid[n][n] 起始点和终止点start,finish | |
装载问题 | 子集树 | ①当前载重量w ②父结点parent,是否左子结点lchild ③指向当前结点的指针bestq | 当前重量currw,最优解bestw,当前处理的结点指针currq | |
无向图的最大割 | 子集树 | ①当前割边数量cut,剩余边数量e ②当前层次lev ③当前解向量x[n] ④重载< | 顶点数n,边数e,邻接矩阵G[n][n] |