什么是分枝限界法
分枝限界法类似于回溯法,也是一种在问题的解空间树上搜索问题解的算法。
但在一般情况下,分枝限界法与回溯法的求解目标不同。回溯法的求解目标是找出解空间树中满足约束条件的所有解,而分枝限界法的求解目标则是找出满足约束条件的一个解,或是在满足约束条件的解中找出使某一目标函数值达到极大或极小的解,即在某种意义下的最优解。
所谓“分枝”就是采用广度优先的策略,依次搜索活结点的所有分枝,也就是所有相邻结点。
求最优解时,选择哪一个子结点?
采用一个限界函数,计算限界函数值,选择一个最有利的子结点作为扩展结点,使搜索朝着解空间树上有最优解的分枝推进,以便尽快地找出一个最优解。
分枝限界法与回溯法的主要区别
分枝限界法的设计思想
设计合适的限界函数
在搜索解空间树时,每个活结点可能有很多孩子结点,其中有些孩子结点搜索下去是不可能产生问题解或最优解的。
可以设计好的限界函数在扩展时删除这些不必要的孩子结点,从而提高搜索效率。
假设活结点si有4个孩子结点,而满足限界函数的孩子结点只有2个,可以删除这2个不满足限界函数的孩子结点,使得从si出发的搜索效率提高一倍。
限界函数设计难以找出通用的方法,需根据具体问题来分析。一般地,先要确定问题解的特性:
目标函数是求最大值:则设计上界限界函数ub(根结点的ub值通常大于或等于最优解的ub值),若si是sj的双亲结点,应满足ub(si)≥ub(sj),当找到一个可行解ub(sk)后,将所有小于ub(sk)的结点剪枝。
目标函数是求最小值:则设计下界限界函数lb(根结点的lb值一定要小于或等于最优解的lb值),若si是sj的双亲结点,应满足lb(si)≤lb(sj),当找到一个可行解lb(sk)后,将所有大于lb(sk)的结点剪枝。
组织活结点表
根据选择下一个扩展结点的方式来组织活结点表,不同的活结点表对应不同的分枝搜索方式。
队列式分枝限界法
优先队列式分枝限界法
队列式分枝限界法
队列式分枝限界法将活结点表组织成一个队列,并按照队列先进先出(FIFO)原则选取下一个结点为扩展结点。步骤如下:
- 将根结点加入活结点队列。
- 从活结点队中取出队头结点,作为当前扩展结点。
- 对当前扩展结点,先从左到右地产生它的所有孩子结点,用约束条件检查,把所有满足约束条件的孩子结点加入活结点队列。
- 重复步骤②和③,直到找到一个解或活结点队列为空为止。
优先队列式分枝限界法
优先队列式分枝限界法的主要特点是将活结点表组组成一个优先队列,并选取优先级最高的活结点成为当前扩展结点。步骤如下:
- 计算起始结点(根结点)的优先级并加入优先队列(与特定问题相关的信息的函数值决定优先级)。
- 从优先队列中取出优先级最高的结点作为当前扩展结点,使搜索朝着解空间树上可能有最优解的分枝推进,以便尽快地找出一个最优解。
- 对当前扩展结点,先从左到右地产生它的所有孩子结点,然后用约束条件检查,对所有满足约束条件的孩子结点计算优先级并加入优先队列。
- 重复步骤②和③,直到找到一个解或优先队列为空为止。
确定最优解的解向量
分枝限界法在搜索解空间树时,结点的处理是跳跃式的,回溯也不是单纯地沿着双亲结点一层一层地向上回溯,因此当搜索到某个叶子结点且该结点对应一个可行解时,如何得到对应的解向量呢?
两种方法:
① 对每个扩展结点保存从根结点到该结点的路径。
每个结点带有一个可能的解向量。这种做法比较浪费空间,但实现起来简单,后面的示例均采用这种方式。
② 在搜索过程中构建搜索经过的树结构。
每个结点带有一个双亲结点指针,当找到最优解时,通过双亲指针找到对应的最优解向量。这种做法需保存搜索经过的树结构,每个结点增加一个指向双亲结点的指针。
采用分枝限界法求解的3个关键问题如下:
(1)如何确定合适的限界函数。
(2)如何组织待处理结点的活结点表。
(3)如何确定解向量的各个分量。
分枝限界法的时间性能
一般情况下,在问题的解向量X=(x1,x2,…,xn)中,分量xi(1≤i≤n)的取值范围为某个有限集合Si=(si1,si2,…,sir)。
问题的解空间由笛卡尔积S1×S2×…×Sn构成:
第1层根结点有|S1|棵子树
第2层有|S1|个结点,第2层的每个结点有|S2|棵子树,第3层有|S1|×|S2|个结点
…
第n+1层有|S1|×|S2|×…×|Sn|个结点,它们都是叶子结点,代表问题的所有可能解
在最坏情况下,时间复杂性是指数阶。