分支界限法
分支限界法常以广度优先或以最小耗费(最大效益)优先的方式搜索问题的解空间树,裁剪那些不能得到最优解的子树以提高搜索效率。
分支界限法解题的一般思路:
(1)分支限界法的求解目标则是找出满足约束条件的一个解,或是在满足约
束条件的解中找出在某种意义下的最优解。
(2)搜索方式:以广度优先或以最小耗费优先的方式搜索解空间树。分支限
界法常以广度优先或以最小耗费(最大效益)优先的方式搜索问题的解空间树。
(3)在分支限界法中,每一个活结点只有一次机会成为扩展结点。活结点一
旦成为扩展结点,就一次性产生其所有儿子结点。在这些儿子结点中,导致不可
行解或导致非最优解的儿子结点被舍弃,其余儿子结点被加入活结点表中。
(4)此后,从活结点表中取下一结点成为当前扩展结点,并重复上述结点扩
展过程。这个过程一直持续到找到所需的解或活结点表为空时为止。
旅行售货员问题
某售货员要到若干城市去推销商品,已知各城市之间的路程(旅费),他要
选定一条从驻地出发,经过每个城市一遍,最后回到驻地的路线,使总的路程(总
旅费)最小。

求解思想:
旅行售货员问题的解空间可以组织成一棵树,从树的根结点到任一叶结点的路径定义了图的一条周游路线。旅行售货员问题要在图 G 中找出费用最小的周游路线。路线是一个带权图。图中各边的费用(权)为正数。图的一条周游路线是包括 V 中的每个顶点在内的一条回路。周游路线的费用是这条路线上所有边的费用之和。
在具体实现时,用邻接矩阵表示所给的图G。在类Traveing中用二维数组a存储图G的邻接矩阵。
template <class Type>
class Traveling
{
public:
Type BBTSP(int *v, Type **, int, Type);
private:
Type **a, //图G的邻接矩阵
NoEdge; //图G的无边标志
int n; //图G的顶点数
};
要找最小费用旅行售货员回路,选用最小堆表示活结点优先队列。最小堆中元素的类型为MinHeapNode。该类型结点包含域x,用于记录当前解;s表示结点在排列树中的层次,从排列树的根结点到该结点的路径为x[0:s],需要进一步搜索的顶点是x[s+1:n-1]。cc表示当前费用,lcost是子树费用的下界,rcost是x[x:n-1]中顶点最小出边费用和。
//队列中元素类型
template <class Type>
class MinHeapNode
{
template <class T>
friend class Traveling;
public:
bool operator < (const MinHeapNode &MH) const
{
return lcost > MH.lcost;
}
private:
Type rcost, //x[s:n-1]中顶点最小出边费用和
lcost, //子树费用的下界
cc; //当前费用
int s, //根结点到当前结点的路径为x[0:s]
*x; //需要进一步搜索的顶点是x[s+1:n-1]
};
算法开始时创建一个最小堆,表示活结点优先队列。堆中每个结点的lcost值是优先队列的优先级。接着计算出图中每个顶点的最小费用出边并用Minout记录。如果所给的有向图中某个顶点没有出边,则该图不可能有回路,算法即告结束。如果每个顶点都有出边,则根据计算出的Minout作算法初始化。算法的第一个扩展结点是排列树中根结点的唯一儿子结点。在该结点处,已确定的回路中唯一顶点为顶点1.初始时有s=0,x[0]=1,x[1:n-1]=(2,3,…,n),cc=0且 rcost = \sum_{j=s}^{n}Minout[i],算法中用bestc记录当前最优值。
template <class Type

最低0.47元/天 解锁文章
2万+

被折叠的 条评论
为什么被折叠?



