运筹优化中的分支定界算法
Posted 喜东东
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了运筹优化中的分支定界算法相关的知识,希望对你有一定的参考价值。
前言
最近意识到对外输出才是王道,有几个好处:
- 便于重新梳理和思考,修补知识结构盲区
- 将内化转为外化,建立影响力
希望每周都有更新,笔耕不缀。如有错漏,敬请雅正。
分支定界算法
分支定界法(branch and bound)是一种求解整数规划问题的最常用算法。这种方法不但可以求解纯整数规划,还可以求解混合整数规划问题。
分枝定界法的主要思路:以最大值问题为例,通常把全部可行解空间反复地分割为越来越小的子集,称为分枝;并且对每个(松弛问题)子集内的解集计算一个最优解并尝试更新目标上界,满足整数约束可行解时则更新目标下界,这称为定界。在每次分枝后,凡是界限超出已知可行解集目标值的那些子集不再进一步分枝,这样,许多子集可不予考虑,这称剪枝。
这个算法非常依赖于上下界的高效评估,如果没有上下界限制,整个算法就会退化到穷举搜索。
The algorithm depends on efficient estimation of the lower and upper bounds of regions/branches of the search space. If no bounds are available, the algorithm degenerates to an exhaustive search.
如果以最大化问题为例,算法过程可以总结为如下步骤:
1.初始化
首先通过启发式方法计算出一个可行解的目标值或负无穷赋值给B (在最大化问题中下界LB与B等价);初始化一个目标优化问题的队列,并将原始问题(A)入队列。例如,求解如下目标最大值,可以初始化B为-inf。
$$ \\begin{aligned} &(A) \\max S=5 x_{1}+8 x_{2} \\\\ &\\left\\{\\begin{array}{l} x_{1}+x_{2} \\leq 6 \\\\ 5 x_{1}+9 x_{2} \\leq 45\\\\ x_{1}, x_{2} \\geq 0 且为整数 \\end{array}\\right. \\end{aligned} $$
2.当前最优解及上下界更新
出队列,暂时不考虑整数约束条件,使用单纯形法在线性空间求解出一个最优解x及目标值B\'。通过上下界的不断更新,不断完成分支操作和剪枝操作。
- 如果x存在不为整数且B\'<UB,领上界UB=B\',并继续向下探索,进入步骤3;(注:不会存在B\'>UB的情况,因为分支后的解空间更小)
- 如果x取值均为整数且B\'>LB,领下界LB=B\',并记录下截至目前的最优解x,该节点停止向下探索;
- 如果B’不在[LB,UB]之间,则可以认为当前节点下不会存在更优的参数组合,停止向下探索,即,被剪枝(毕竟减少了约束条件还不能超过当前的LB,看来是没有希望了;)
(注:下界由整数解控制,上界由线性解控制)
例如,不考虑整数约束条件,A转为B0:(可以认为A式的解是B0解的子集)
$$ \\begin{aligned} &(B_{0}) \\max S=5 x_{1}+8 x_{2} \\\\ &\\left\\{\\begin{array}{l} x_{1}+x_{2} \\leq 6 \\\\ 5 x_{1}+9 x_{2} \\leq 45\\\\ x_{1}, x_{2} \\geq 0 \\end{array}\\right. \\end{aligned} $$
根据单纯形法求得x1=2.25,x2=3.75,S0=41.25
3.对节点进行分支
根据单纯形法求出的变量结果,选择一个变量进行拆解:对最优解对应变量的前后整数作为拆分。
e.g.将在B0拆解为B1和B2,并将B1、B2放入队列;由于上一步松弛后最优解的x2=3.75,原约束改为<=3和>=4。(注:放入队列时,B1、B2均带有“整数约束”)
$$ \\begin{aligned} &\\left(B_{1}\\right) \\max S=5 x_{1}+8 x_{2}\\\\ &\\left\\{\\begin{array}{l} x_{1}+x_{2} \\leq 6\\\\ {5 x_{1}+9 x_{2} \\leq 45} \\\\ \\begin{array}{l} x_{2} \\leq 3 \\\\ x_{1}, x_{2} \\geq 0 且为整数 \\end{array} \\end{array}\\right.\\\\ \\end{aligned} $$
$$ \\begin{aligned} &\\left(B_{2}\\right) \\max S=5 x_{1}+8 x_{2}\\\\ &\\left\\{\\begin{array}{l} x_{1}+x_{2} \\leq 6\\\\ {5 x_{1}+9 x_{2} \\leq 45} \\\\ \\begin{array}{l} x_{2} \\geq 4 \\\\ x_{1}, x_{2} \\geq 0 且为整数 \\end{array} \\end{array}\\right.\\\\ \\end{aligned} $$
分拆后入队列的方式可以分为广度优先搜索、深度优先搜索和最佳优先搜索。
- Breadth-first search (BFS):广度优先搜索,就是横向搜索,先搜索同层的节点。再一层一层往下。这种搜索可以用FIFO queue实现。
- Depth-first search (DFS):深度优先搜索,就是纵向搜索,先一个分支走到底,再跳到另一个分支走到底。这种搜索可以用LIFO queue也就是栈实现。
- Best-First Search:最佳优先搜索,最佳优先搜索算法是一种启发式搜索算法(Heuristic Algorithm),其基于广度优先搜索算法,不同点是其依赖于估价函数对将要遍历的节点进行估价,选择代价小的节点进行遍历,直到找到目标点为止。这种搜索可以用优先队列priority queue来实现。
4.终止判定:队列为空时,结束计算。
维基百科的介绍:(最小化问题)
- Using a heuristic, find a solution xh to the optimization problem. Store its value, B = f(x_h). (If no heuristic is available, set B to infinity.) B will denote the best solution found so far, and will be used as an upper bound on candidate solutions.
- Initialize a queue to hold a partial solution with none of the variables of the problem assigned.
- Loop until the queue is empty:
3.1. Take a node N off the queue.
3.2. If N represents a single candidate solution x and f(x) < B, then x is the best solution so far. Record it and set B ← f(x).
3.3. Else, branch on N to produce new nodes Ni. For each of these:
3.3.1. If bound(N_i) > B, do nothing; since the lower bound on this node is greater than the upper bound of the problem, it will never lead to the optimal solution, and can be discarded.
3.3.2. Else, store Ni on the queue.
参考
几篇比较不错的文章:1,2,3
以上是关于运筹优化中的分支定界算法的主要内容,如果未能解决你的问题,请参考以下文章