分支界定算法的主要思想是把问题的可行解划分为多个子集,对子集进行系统化的评估直到最优解找到。分支界定只是一种算法框架,因为如何构造子集、在每个子集如何搜索最优解可以按不同情况有不同的具体实现,当用于求解线性整数优化问题时,就需要结合一般的线性优化算法或者求解器来实现。下面先用一个实例来说明算法的思路,然后用代码实现一下。
一家工厂打算购买两种设备,印刷机和车床。老板估计每台印刷机每台可以增加$100的利润,每台车床每天可以增加$150的利润;但同时购买数量也会收到预算和场地面积的约束,每台印刷机或车床的花费和占地如下表所示:
Machine | Required Floor Space | Purchase Price |
---|---|---|
印刷机 | 15 | $8000 |
车床 | 30 | $4000 |
老板的预算是$40000,并且现在有200平方的空地;工厂老板应该怎样购买来让每天的利润最大?
如果我们设x1x_1x1是购买多少台印刷机,x2x_2x2是购买多少台车床,那么可以写出优化问题的模型
maximieZ=100x1+150x2subject to8000x1+4000x2≤4000015x1+30x2≤200x1,x2≥0 and integer \begin{aligned} maximie\quad& Z=100x_1+150x_2\\ subject\ to\quad& 8000x_1+4000x_2\leq 40000 \\ & 15x_1+30x_2\leq 200 \\ & x_1,x_2\geq 0\ and\ integer \end{aligned} maximiesubject toZ=100x1+150x28000x1+4000x2≤4000015x1+30x2≤200x1,x2≥0 and integer
相比线性优化模型,上面的数学模型就多出必须为整数的约束。如果我们把整数约束去掉,那么可以得到最优解:
x1=2.22,x2=5.56, and Z=1055.56 x_1=2.22,x_2=5.56,\ and\ Z=1055.56 x1=2.22,x2=5.56, and Z=1055.56
如果我们把这个解四舍五入,可以得到一个可行的整数解
x1=2,x2=5, and Z=950 x_1=2,x_2=5,\ and\ Z=950 x1=2,x2=5, and Z=950
但是这个整数解并不是实际的最优解,因为一旦加上整数约束,线性优化模型往往是非凸的,线性优化算法往往无能为力。而分支界定法则是把原问题进行松弛(即去掉整数约束),以松弛线性模型为根节点不断地划分子问题和更新问题上下界,通过评判上下界来忽略无效子问题和停止算法。首先我们构造根节点,该节点就是上面模型去掉整数约束后的松弛模型,对于这个松弛线性最大化问题,我们构造一下上下界,用它的最优解(Z=1055.56Z=1055.56Z=1055.56)作为问题的上界,用四舍五入后的整数解(x1=2,x2=5,Z=950x_1=2,x_2=5,Z=950x1=2,x2=5,Z=950)作为下界;上下界的意义在于,原始整数优化模型的解一定是在上下界之间的,所以对于所有最优解比下界更小的子问题,我们可以直接忽略;而子问题的上界一定不会大于父问题,通过不断分支,这个上下界间的范围将不断缩减。
因为根节点的最优解不是整数解,所以我们选择一个非整数解进行分支。这里我们采取选择离四舍五入值最远的变量,对于根节点,即选择了变量x2=5.56x_2=5.56x2=5.56。我们以变量x2x_2x2为划分点向下分支出两个子问题,分别在根节点的松弛优化模型的基础上新增约束x2≤5x_2\leq5x2≤5和x2≥6x_2\geq6x2≥6,也就是说,对于左侧的子节点2,松弛优化模型为:
maximieZ=100x1+150x2subject to8000x1+4000x2≤4000015x1+30x2≤200x1,x2≥0x2≤5 \begin{aligned} maximie\quad& Z=100x_1+150x_2\\ subject\ to\quad& 8000x_1+4000x_2\leq 40000 \\ & 15x_1+30x_2\leq 200 \\ & x_1,x_2\geq 0\\ & x_2 \leq5 \end{aligned} maximiesubject toZ=100x1+150x28000x1+4000x2≤4000015x1+30x2≤200x1,x2≥0x2≤5
右侧子节点3的问题模型为:
maximieZ=100x1+150x2subject to8000x1+4000x2≤4000015x1+30x2≤200x1,x2≥0x2≥6 \begin{aligned} maximie\quad& Z=100x_1+150x_2\\ subject\ to\quad& 8000x_1+4000x_2\leq 40000 \\ & 15x_1+30x_2\leq 200 \\ & x_1,x_2\geq 0\\ & x_2 \geq6 \end{aligned} maximiesubject toZ=100x1+150x28000x1+4000x2≤4000015x1+30x2≤200x1,x2≥0x2≥6
对于节点2,可以求得最优解为x1=2.5,x2=5,Z=1000x_1=2.5,x_2=5,Z=1000x1=2.5,x2=5,Z=1000,而节点3的最优解为x1=1.33,x2=6,Z=1033.33x_1=1.33,x_2=6,Z=1033.33x1=1.33,x2=6,Z=1033.33,这两个解可分别作为这两个节点的上界。可以看到这两个上界都小于根节点的上界,因为每一次分支,都是在原松弛优化模型的基础上新增约束,它的最优解肯定不会好过原问题。再来分析下界,因为这两个子节点的解都不是完整整数解,所以这两个节点下界保持不变,仍是950
我们还没有找到最优可行解,所以要从结点2或者3继续分支。选择哪个结点呢,这里我们按上界更大优先的原则来选取结点,也就是从结点3进行分支。采用这种原则其实是一种间接地剪枝,如果某个结点的最优解是非整数解并且小于当前的全局下界(即上界比下界更小),那么需要把这个结点及其所有子节点都从搜索数里去除,它们的解肯定不会是最优解了,通过上界越大越优先的原则来选取,这些结点实际上根本不会被选中。结点3的x2x_2