优化| 割平面算法(2): Cover Cuts, Strengthening, Separation及其拓展(理论与实战详解)

news2024/10/7 10:18:14

【MIP Cutting plane method】-1: Cover cuts

    • MIP的标准形式
    • 什么是Cover Cuts
    • Cover Cuts的详细案例
    • Stronger Cover Cuts及其案例
    • Separation for Cover Cuts
    • 用Separation生成 Cover Cuts的详细例子
    • 调用Gurobi验证Cover Cuts和Stronger Cover Cuts的作用
      • 线性松弛模型的解
      • 加入Cover Cut
      • 加入Stronger Cover Cut
      • Separation for Cover Cuts
    • 小结
    • 参考文献

作者:刘兴禄,清华大学,清华大学深圳国际研究生院,清华-伯克利深圳学院,博士在读

MIP的标准形式

MIP的一般形式如下:
min ⁡ ∑ i ∈ N c i x i s . t . ∑ i ∈ N a i x i ⩽ b , x i ∈ Z , ∀ i ∈ I . \begin{align} \min \quad &\sum_{i\in N} c_i x_i && \\ s.t. \quad & \sum_{i\in N} a_i x_i \leqslant b, && \\ \quad &x_{i} \in \mathbb{Z}, && \forall i \in I. \end{align} mins.t.iNcixiiNaixib,xiZ,iI.
其中, I I I为取值要求为整数的变量的下标集合。

求解MIP的最高效的通用算法为Branch and cut。该方法是将Cutting plane method嵌入到Branch and bound框架中,从而达到显著加速求解MIP的效果的一种精确算法框架。Cutting plane算法用于提升全局界限,收紧可行域,而Branch and bound用于搜索可行域。

本文主要来介绍一种基本的Cutting plane算法,即:Cover Cut。此外,本文还对其拓展方法进行了介绍,并提供了相应的验证代码。

假设有下面的MIP或者IP:
min ⁡ ∑ i ∈ N c i x i s . t . ∑ i ∈ N a i x i ⩽ b , x i ∈ { 0 , 1 } , ∀ i ∈ N . \begin{align} \min \quad &\sum_{i\in N} c_i x_i && \\ s.t. \quad & \sum_{i\in N} a_i x_i \leqslant b, && \\ \quad &x_{i} \in \{0, 1\}, && \forall i \in N. \end{align} mins.t.iNcixiiNaixib,xi{0,1},iN.

下面我们基于该模型来介绍Cover cuts.

什么是Cover Cuts

考虑下面的约束

∑ j = 1 n a j x j ⩽ b , \begin{align} \sum_{j= 1}^{n} a_j x_j \leqslant b, && \end{align} j=1najxjb,

是否可以找到上面约束的一个有效割平面?

可以基于Cover来生成有效的割平面。首先我们来介绍Cover的概念。

Cover
集合 C ⊆ N = { 1 , 2 , ⋯   , n } C\subseteq N = \{1, 2, \cdots, n\} CN={1,2,,n}被称之为一个Cover,当
∑ j ∈ C a j > b \begin{align} \sum_{j \in C} a_j > b \end{align} jCaj>b

Minimal Cover
如果 C C C是一个Cover,并且对于任意的 j ∈ C j \in C jC,而言,集合 C \ { j } C\backslash\{j\} C\{j}都不再是Cover,则称 C C C是一个最小Cover。

Cover cut
如果集合 C ⊆ N = { 1 , 2 , ⋯   , n } C\subseteq N = \{1, 2, \cdots, n\} CN={1,2,,n}是一个Cover,则下面的表达式是原问题的一个有效不等式:
∑ j ∈ C x j ⩽ ∣ C ∣ − 1. \begin{align} \sum_{j \in C} x_j \leqslant |C| - 1. \end{align} jCxjC1.

Cover Cuts的详细案例

考虑下面的约束
10 x 1 + 7 x 2 + 7 x 3 + 5 x 4 + 4 x 5 + 4 x 6 + x 7 ⩽ 18. \begin{align} 10x_1 + 7x_2 + 7x_3 + 5x_4 + 4x_5 + 4x_6 + x_7 \leqslant 18. \end{align} 10x1+7x2+7x3+5x4+4x5+4x6+x718.

我们可以很轻易地找到一个Cover C = { 1 , 2 , 3 } C = \{1, 2, 3\} C={1,2,3},因为 a 1 + a 2 + a 3 = 10 + 7 + 7 = 24 > 19 a_1+ a_2 + a_3 = 10+7+7=24 > 19 a1+a2+a3=10+7+7=24>19,从而可以推导出下面的有效不等式:

x 1 + x 2 + x 3 ⩽ 2. \begin{align} x_1 + x_2 + x_3 \leqslant 2. \end{align} x1+x2+x32.

类似地,我们可以很轻易地找到一个Cover C = { 3 , 4 , 5 , 6 } C = \{3, 4, 5, 6\} C={3,4,5,6},因为 a 3 + a 4 + a 5 + a 6 = 7 + 5 + 4 + 4 = 20 > 19 a_3+ a_4 + a_5 + a_6 = 7+5+4+4=20 > 19 a3+a4+a5+a6=7+5+4+4=20>19,从而可以推导出下面的有效不等式:

x 3 + x 4 + x 5 + x 6 ⩽ 3. \begin{align} x_3 + x_4 + x_5 + x_6 \leqslant 3. \end{align} x3+x4+x5+x63.

Stronger Cover Cuts及其案例

Stronger Cover cut
如果集合 C ⊆ N = { 1 , 2 , ⋯   , n } C\subseteq N = \{1, 2, \cdots, n\} CN={1,2,,n}是一个Cover,则下面的表达式是原问题的一个有效不等式:
∑ j ∈ E ( C ) x j ⩽ ∣ C ∣ − 1. \begin{align} \sum_{j \in E(C)} x_j \leqslant |C| - 1. \end{align} jE(C)xjC1.
其中,
E ( C ) = C ∪ { j ∣ a j ⩾ a i , ∀ i ∈ C } \begin{align} E(C) = C \cup \{j | a_j \geqslant a_i, \forall i \in C\} \end{align} E(C)=C{jajai,iC}
即,将比 C C C中的序号对应的决策变量的约束系数都大的变量挑选出来。

再次考虑上面的约束。考虑 C = { 3 , 4 , 5 , 6 } C = \{3, 4, 5,6\} C={3,4,5,6},则容易得到 E ( C ) = { 1 , 2 , 3 , 4 , 5 , 6 } E(C) = \{1,2,3, 4, 5,6\} E(C)={1,2,3,4,5,6},因此可以推出Stronger Cover Cuts为:

x 1 + x 2 + x 3 + x 4 + x 5 + x 6 ⩽ 3. \begin{align} x_1 + x_2 + x_3 + x_4 + x_5 + x_6 \leqslant 3. \end{align} x1+x2+x3+x4+x5+x63.

上面的Stronger Cover Cuts要更紧凑。

下面我们用代码来验证Cover Cuts和Stronger Cover Cuts对于收紧下界的用处。

Separation for Cover Cuts

考虑有MIP的MILP的最优解是 x ∗ \mathbf{x}^* x,我们想,是否存在一个Cover Cut可以将这个 x ∗ \mathbf{x}^* x给割去。Separation for Cover Cuts就是为了达到这个目的。

在介绍Separation for Cover Cuts之前,我们先来看下面的一些分析。

考虑下面的Cover cuts:

∑ j ∈ C x j ⩽ ∣ C ∣ − 1. \begin{align} \sum_{j \in C} x_j \leqslant |C| - 1. \end{align} jCxjC1.
上面的约束是说, C C C中的元素不能被全选。我们考虑其反面,则可知, C C C中至少有一个元素不被选(落选)。因此,这个Cut可以被重写为

∑ j ∈ C ( 1 − x j ) ⩾ 1. \begin{align} \sum_{j \in C} (1 - x_j) \geqslant 1. \end{align} jC(1xj)1.

  • 注意: x j x_j xj表示 j j j是否被选, ( 1 − x j ) (1-x_j) (1xj)就表示 j j j是否落选。

接下来我们思考,如何将最优松弛小数解 x ∗ \mathbf{x}^* x给割去呢?一个直观的想法是,找到一个Cover C C C 满足下面的条件:

∑ j ∈ C a j > b ( 即集合 C 是一个Cover ) ∑ j ∈ C ( 1 − x j ∗ ) < 1 ( 但是当前小数最优解 x ∗ 违背了Cover Cut ) \begin{align} &\sum_{j \in C} a_j > b \quad&& (\text{即集合$C$是一个Cover}) \\ &\sum_{j \in C} (1 - x_j^*) < 1 \quad && (\text{但是当前小数最优解$\mathbf{x}^*$违背了Cover Cut}) \end{align} jCaj>bjC(1xj)<1(即集合C是一个Cover)(但是当前小数最优解x违背了Cover Cut)

也就是说,若整数最优解为 x i n t ∗ \mathbf{x}_{int}^* xint,则 x i n t ∗ \mathbf{x}_{int}^* xint一定满足上面的Cover Cut,但是如果我们能找到一个Cover C C C,使得当前最优松弛小数解 x ∗ \mathbf{x}^* x不满足Cover Cut,这说明我们找到了一个Cover Cut,可以将当前最优松弛小数解 x ∗ \mathbf{x}^* x割去,从而提升了界限,缩小了可行域。

但是问题是,这个 C C C如何去找呢?

有一个很不错的办法是,构建一个整数规划模型去找,该模型如下:

min ⁡ ∑ i ∈ N ( 1 − x j ∗ ) z j s . t . ∑ i ∈ N a j z j > b , z j ∈ { 0 , 1 } , ∀ i ∈ N . \begin{align} \min \quad &\sum_{i\in N} (1 - x_j^*) z_j && \\ s.t. \quad & \sum_{i\in N} a_j z_j > b, && \\ \quad &z_{j} \in \{0, 1\}, && \forall i \in N. \end{align} mins.t.iN(1xj)zjiNajzj>b,zj{0,1},iN.
其中 z j z_j zj表示下标 j j j是否包含在要找的集合 C C C中,是一个辅助0-1决策变量。

求解上述模型,如果最优值小于1,则我们就可以找到一个Cut,其中 C = { j ∣ z j = 1 , ∀ j ∈ N } C = \{j | z_j=1, \forall j \in N\} C={jzj=1,jN}. 即,若 z j = 1 z_j = 1 zj=1,则其下标就会被加入到 C C C中。

用Separation生成 Cover Cuts的详细例子

考虑下面的约束
45 x 1 + 46 x 2 + 79 x 3 + 54 x 4 + 53 x 5 + 125 x 6 ⩽ 178. \begin{align} 45x_1 + 46x_2 + 79x_3 + 54x_4 + 53x_5 + 125x_6 \leqslant 178. \end{align} 45x1+46x2+79x3+54x4+53x5+125x6178.
假设我们得到的解为:
x ∗ = ( 0 , 0 , 3 4 , 1 2 , 1 , 0 ) . \begin{align} \mathbf{x}^* = \left(0, 0, \frac{3}{4}, \frac{1}{2}, 1, 0\right). \end{align} x=(0,0,43,21,1,0).
我们如何来获得一个Cover Cut呢?我们来构建下面的模型:

min ⁡ ∑ i ∈ N ( 1 − x j ∗ ) z j s . t . ∑ i ∈ N a j z j > b , z j ∈ { 0 , 1 } , ∀ i ∈ N . \begin{align} \min \quad &\sum_{i\in N} (1 - x_j^*) z_j && \\ s.t. \quad & \sum_{i\in N} a_j z_j > b, && \\ \quad &z_{j} \in \{0, 1\}, && \forall i \in N. \end{align} mins.t.iN(1xj)zjiNajzj>b,zj{0,1},iN.

写成具体的形式即:

min ⁡ z 1 + z 2 + 1 4 z 3 + 1 2 z 4 + z 6 s . t . 45 z 1 + 46 z 2 + 79 z 3 + 54 z 4 + 53 z 5 + 125 z 6 > 178. z 1 , z 2 , z 3 , z 4 , z 5 , z 6 ∈ { 0 , 1 } . \begin{align} \min \quad & z_1 + z_2 + \frac{1}{4}z_3 + \frac{1}{2}z_4 + z_6 \\ s.t. &45z_1 + 46z_2 + 79z_3 + 54z_4 + 53z_5 + 125z_6 > 178. \\ \quad &z_1, z_2, z_3, z_4,z_5, z_6 \in \{0, 1\}. \end{align} mins.t.z1+z2+41z3+21z4+z645z1+46z2+79z3+54z4+53z5+125z6>178.z1,z2,z3,z4,z5,z6{0,1}.

用Python调用Gurobi求解这个模型,代码如下:

from gurobipy import *

model = Model()
z = {}
for i in range(1, 7):
    z[i] = model.addVar(lb=0, ub=1, vtype=GRB.INTEGER, name='z_'+str(i))

model.setObjective(z[1] + z[2] + 0.25*z[3] + 0.5*z[4] + z[6], GRB.MINIMIZE)

model.addConstr(45*z[1] + 46*z[2] + 79*z[3] + 54*z[4] + 53*z[5] + 125*z[6]  >= 177.99999)

model.optimize()

print('Obj: {}'.format(model.ObjVal))
for i in range(1, 7):
    print('{} = {}'.format(z[i].VarName, z[i].x))

求解结果如下:

Best objective 7.500000000000e-01, best bound 7.500000000000e-01, gap 0.0000%
Obj: 0.75
z_1 = -0.0
z_2 = -0.0
z_3 = 1.0
z_4 = 1.0
z_5 = 1.0
z_6 = -0.0

可见,目标函数 Obj ∗ = 0.75 < 1 \text{Obj}^* = 0.75<1 Obj=0.75<1,因此可以找到一个Cover,即 C = { 3 , 4 , 5 } C=\{3,4,5\} C={3,4,5}。可以找到一个Cover Cut,为:
x 3 + x 4 + x 5 ⩽ 2. \begin{align} x_3 + x_4 + x_5 \leqslant 2. \end{align} x3+x4+x52.

此外,我们可以继续探讨上面的Separation model,我们将 z j z_j zj 1 − y j 1-y_j 1yj代替,则得到:

min ⁡ ∑ i ∈ N ( 1 − x j ∗ ) ( 1 − y j ) s . t . ∑ i ∈ N a j ( 1 − y j ) > b , y j ∈ { 0 , 1 } , ∀ i ∈ N . \begin{align} \min \quad &\sum_{i\in N} (1 - x_j^*) (1-y_j) && \\ s.t. \quad & \sum_{i\in N} a_j (1-y_j) > b, && \\ \quad &y_{j} \in \{0, 1\}, && \forall i \in N. \end{align} mins.t.iN(1xj)(1yj)iNaj(1yj)>b,yj{0,1},iN.

进一步,模型可以转化为

max ⁡ ∑ i ∈ N ( 1 − x j ∗ ) y j s . t . ∑ i ∈ N a j y j < ∑ i ∈ N a j − b , y j ∈ { 0 , 1 } , ∀ i ∈ N . \begin{align} \max \quad &\sum_{i\in N} (1 - x_j^*) y_j && \\ s.t. \quad & \sum_{i\in N} a_j y_j < \sum_{i\in N} a_j - b, && \\ \quad &y_{j} \in \{0, 1\}, && \forall i \in N. \end{align} maxs.t.iN(1xj)yjiNajyj<iNajb,yj{0,1},iN.

这就可以转化为一个背包问题

调用Gurobi验证Cover Cuts和Stronger Cover Cuts的作用

考虑下面的0-1背包问题的整数规划模型。

max ⁡ 5 x 1 + 2 x 2 + 4 x 3 + 2 x 4 + 3 x 5 + 3 x 6 + 2 x 7 s . t . 10 x 1 + 7 x 2 + 7 x 3 + 5 x 4 + 4 x 5 + 4 x 6 + x 7 ⩽ 18. x 1 , x 2 , x 3 , x 4 , x 5 , x 6 , x 7 ∈ { 0 , 1 } . \begin{align} \max \quad & 5 x_1 + 2x_2 + 4x_3 + 2x_4 + 3x_5 + 3x_6 + 2 x_7 \\ s.t. &10x_1 + 7x_2 + 7x_3 + 5x_4 + 4x_5 + 4x_6 + x_7 \leqslant 18. \\ \quad &x_1, x_2, x_3, x_4,x_5, x_6, x_7 \in \{0, 1\}. \end{align} maxs.t.5x1+2x2+4x3+2x4+3x5+3x6+2x710x1+7x2+7x3+5x4+4x5+4x6+x718.x1,x2,x3,x4,x5,x6,x7{0,1}.

该问题的整数最优解为:
x 3 = x 5 = x 6 = 1 Obj ∗ = 12 \begin{align} &x_3=x_5=x_6=1 \\ &\text{Obj}^* = 12 \end{align} x3=x5=x6=1Obj=12

线性松弛模型的解

我们用Python调用Gurobi求解上述模型的线性松弛,代码如下:

from gurobipy import *

model = Model()
x = {}
for i in range(1, 8):
    x[i] = model.addVar(lb=0, ub=1, vtype=GRB.CONTINUOUS, name='x_'+str(i))

model.setObjective(5*x[1] + 2*x[2] + 4*x[3] + 2*x[4] + 3*x[5] + 3*x[6] + 2*x[7], GRB.MAXIMIZE)

model.addConstr(10*x[1] + 7*x[2] + 7*x[3] + 5*x[4] + 4*x[5] + 4*x[6] + x[7] <= 18)

model.optimize()

print('Obj: {}'.format(model.ObjVal))
for i in range(1, 7):
    print('{} = {}'.format(x[i].VarName, x[i].x))

求解结果如下:

Obj: 13.0
x_1 = 0.2
x_2 = 0.0
x_3 = 1.0
x_4 = 0.0
x_5 = 1.0
x_6 = 1.0
x_7 = 1.0

这说明此时, U B = 13 UB=13 UB=13,但是是小数解。

加入Cover Cut

我们尝试生成一个Cover Cut:

首先加入Cover Cut 1:
x 1 + x 2 + x 3 ⩽ 2. \begin{align} x_1 + x_2 + x_3 \leqslant 2. \end{align} x1+x2+x32.

发现加入后, U B = 13 UB=13 UB=13,没变。

我们继续加入Cover Cut 2: x 3 + x 4 + x 5 + x 6 ⩽ 3. \begin{align} x_3 + x_4 + x_5 + x_6 \leqslant 3. \end{align} x3+x4+x5+x63.
发现加入后, U B = 13 UB=13 UB=13,依然没有变。

接下来我们生成所有的Cover Cut,具体如下:

x 1 + x 2 + x 3 ⩽ 2 x 1 + x 2 + x 4 ⩽ 2 x 1 + x 2 + x 5 ⩽ 2 x 1 + x 2 + x 6 ⩽ 2 x 1 + x 3 + x 4 ⩽ 2 x 1 + x 3 + x 5 ⩽ 2 x 1 + x 3 + x 6 ⩽ 2 x 2 + x 3 + x 4 ⩽ 2 x 3 + x 4 + x 5 + x 6 ⩽ 3 \begin{align*} &x_1 + x_2 + x_3 \leqslant 2 \\ &x_1 + x_2 + x_4 \leqslant 2 \\ &x_1 + x_2 + x_5 \leqslant 2 \\ &x_1 + x_2 + x_6 \leqslant 2 \\ &x_1 + x_3 + x_4 \leqslant 2 \\ &x_1 + x_3 + x_5 \leqslant 2 \\ &x_1 + x_3 + x_6 \leqslant 2 \\ &x_2 + x_3 + x_4 \leqslant 2 \\ &x_3 + x_4 + x_5 + x_6 \leqslant 3 \end{align*} x1+x2+x32x1+x2+x42x1+x2+x52x1+x2+x62x1+x3+x42x1+x3+x52x1+x3+x62x2+x3+x42x3+x4+x5+x63

将上述Cover Cut全部加入到模型,求解的结果为:

Obj: 12.75
x_1 = 0.25
x_2 = 0.0
x_3 = 0.75
x_4 = 0.25
x_5 = 1.0
x_6 = 1.0
x_7 = 1.0

可以看到,目标函数变化为12.75,略有改进。

实际上,Cover Cuts的效果一般不会太理想,因此需要加入更强的Cut。

加入Stronger Cover Cut

我们加入Stronger Cover Cut 1:

x 1 + x 2 + x 3 + x 4 + x 5 + x 6 ⩽ 3. \begin{align} x_1 + x_2 + x_3 + x_4 + x_5 + x_6 \leqslant 3. \end{align} x1+x2+x3+x4+x5+x63.

代码如下:

model.addConstr(10*x[1] + 7*x[2] + 7*x[3] + 5*x[4] + 4*x[5] + 4*x[6] + x[7] <= 18)
model.addConstr(x[1] + x[2] + x[3] + x[4] + x[5] + x[6] <= 3)

求解结果如下:

Obj: 12.666666666666666
x_1 = 0.3333333333333333
x_2 = 0.0
x_3 = 1.0
x_4 = 0.0
x_5 = 0.6666666666666667
x_6 = 1.0
x_7 = 1.0

发现加入Stronger Cover Cut 1后, U B = 12.67 UB=12.67 UB=12.67,有所改善,说明Stronger Cover Cut 1有效。一个Stronger Cover Cut 1就比9个Cover Cut效果更好。

我们来生成所有的Stronger Cover Cut,可以得到

x 1 + x 2 + x 3 + x 4 ⩽ 2 x 1 + x 2 + x 3 + x 4 + x 5 + x 6 ⩽ 3 \begin{align*} &x_1 + x_2 + x_3 + x_4 \leqslant 2 \\ &x_1 + x_2 + x_3 + x_4 + x_5 + x_6 \leqslant 3 \end{align*} x1+x2+x3+x42x1+x2+x3+x4+x5+x63

加入所有的Stronger Cover Cut之后,求解结果没有进一步改进。

接下来我们继续尝试Separation的办法。

Separation for Cover Cuts

我们基于加入了所有Stronger Cover Cut之后的模型继续添加Cuts。

可知,当前解为

x ∗ = ( 1 3 , 0 , 1 , 0 , 2 3 , 1 , 1 ) . \begin{align} \mathbf{x}^* = \left(\frac{1}{3}, 0, 1, 0, \frac{2}{3}, 1, 1\right). \end{align} x=(31,0,1,0,32,1,1).

构建Separation模型,如下:

min ⁡ 2 3 z 1 + z 2 + z 4 + 1 3 z 5 s . t . 10 z 1 + 7 z 2 + 7 z 3 + 5 z 4 + 4 z 5 + 4 z 6 + z 7 > 18. z 1 , z 2 , z 3 , z 4 , z 5 , z 6 ∈ { 0 , 1 } . \begin{align} \min \quad & \frac{2}{3}z_1 + z_2 + z_4 + \frac{1}{3}z_5 \\ s.t. &10z_1 + 7z_2 + 7z_3 + 5z_4 + 4z_5 + 4z_6 + z_7 > 18. \\ \quad &z_1, z_2, z_3, z_4,z_5, z_6 \in \{0, 1\}. \end{align} mins.t.32z1+z2+z4+31z510z1+7z2+7z3+5z4+4z5+4z6+z7>18.z1,z2,z3,z4,z5,z6{0,1}.

使用Python调用Gurobi求解上述模型,具体代码为:

from gurobipy import *

model = Model()
x = {}
for i in range(1, 8):
    x[i] = model.addVar(lb=0, ub=1, vtype=GRB.BINARY, name='z_'+str(i))

model.setObjective(0.67*x[1] + 1*x[2] + 0*x[3] + 1*x[4] + 0.33*x[5] + 0*x[6] + 0*x[7], GRB.MINIMIZE)

model.addConstr(10*x[1] + 7*x[2] + 7*x[3] + 5*x[4] + 4*x[5] + 4*x[6] + x[7] >= 17.9999999)

model.optimize()

print('Obj: {}'.format(model.ObjVal))
for i in range(1, 8):
    print('{} = {}'.format(x[i].VarName, x[i].x))

求解结果为:

Obj: 0.67
z_1 = 1.0
z_2 = 0.0
z_3 = 1.0
z_4 = 0.0
z_5 = 0.0
z_6 = 1.0
z_7 = 1.0

可知, Obj ∗ = 0.67 < 1 \text{Obj}^* = 0.67 < 1 Obj=0.67<1,因此可以生成一个Cover C = { 1 , 3 , 6 , 7 } C = \{1, 3, 6, 7\} C={1,3,6,7},构造下面的Cover Cut:
x 1 + x 3 + x 6 + x 7 ⩽ 3 \begin{align} &x_1 + x_3 + x_6 + x_7 \leqslant 3 \end{align} x1+x3+x6+x73
加入该Cut,可得小数最优解依然为12.67,没有改进。说明没有生成新的有效割。

但是如果只加入 x 1 + x 3 + x 6 + x 7 ⩽ 3 x_1 + x_3 + x_6 + x_7 \leqslant 3 x1+x3+x6+x73,不加入Stronger Cover Cut,则该Cover Cut还是有效的,加入后 Obj ∗ = 12.8 \text{Obj}^* = 12.8 Obj=12.8,比不加任何Cut的界限紧。

在这里插入图片描述

小结

本文介绍了求解混合整数规划问题的Cutting plane method中的Cover Cut,具体包括基本的Cover Cut,以及加强版本的Stronger Cover Cut以及用于割去当前小数解的Separation的方法。

为了帮助读者直观理解这些方法,我们提供了相应的完整代码。每一种Cut的效率随问题而异,读者需要自行验证。

参考文献

[1]. Wolsey L A. Integer programming[M]. John Wiley & Sons, 2020.
[2]. Discrete Optimization: cover cuts branch and cut seven bridges traveling salesman.https://www.youtube.com/watch?v=8yajCJKezZQ

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/496072.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

领域分类/识别方案

将用户输入与预定义的领域进行匹配 针对领域分类任务&#xff0c;如上图所示&#xff0c;我们首先会从不同的业务中收集大量的业务数据&#xff0c;作为基础的训练数据&#xff0c;虽然这些数据来自不同的业务&#xff0c;但是依然存在一些问题&#xff0c;主要有以下两方面&am…

YOLOv7测距+碰撞检测

YOLOv7测距碰撞检测 1. 相关配置2. 测距原理3. 标定和测距4. 碰撞检测4.1 相关代码4.2 主代码 5. 实验效果 相关链接 1. YOLOV5 单目测距&#xff08;python&#xff09; 2. YOLOV7 单目测距&#xff08;python&#xff09; 3. 具体实现效果已在Bilibili发布&#xff0c;点击…

vscode+gdbserver实现图形化调试Linux应用

一、环境&#xff1a; 1.远程Linux主机Ubuntu22.04&#xff1b; 2.vscode 1.76 二、环境搭建 1.Ubuntu 安装gdb、gdbserver、openssh-server 2.vscode 安装Remote Development、C/C 3.远程连接Linux 点击左下角的绿色按钮&#xff0c;然后选择connect to host----->…

Day1 组队竞赛、删除公共字符

✨个人主页&#xff1a; 北 海 &#x1f389;所属专栏&#xff1a; C/C相关题解 &#x1f383;操作环境&#xff1a; Visual Studio 2019 版本 16.11.17 文章目录 选择题1.C基础语法 编程题组队竞赛删除公共字符 选择题 1.C基础语法 题目&#xff1a;以下程序的运行结果是&am…

RSA加密为什么能保证安全

问题&#xff1a;我们都知道RSA加密是安全的&#xff0c;但是我们在使用的使用&#xff0c;怎么使用才能保证数据的安全传输呢&#xff1f; 一、原则&#xff1a;公钥机密、私钥解密、私钥签名、公钥验签 公钥私钥都可以加密和解密数据&#xff0c;但是因为持有公钥和私钥的人…

【Elsevier】中科院2区TOP, 高被引119篇, 稳定检索22年, 1周可见刊,5月15截稿~

一、【期刊简介】 中科院2区软计算类SCI (TOP) 【期刊概况】IF:8.0-9.0, JCR1区, 中科院2区&#xff1b; 【终审周期】走期刊部系统&#xff0c;3-5个月左右录用&#xff1b; 【检索情况】SCI&EI双检&#xff1b;正刊&#xff1b; 【数据库收录年份】2001年&#xff1…

【测试】概念篇

目录 &#x1f31f;一、了解软件测试 &#x1f308;1、什么是软件测试 &#x1f308;2、软件测试与开发的区别&#xff08;常考&#xff09; &#x1f308;3、一个优秀的软件测试人员应该具备的素质 &#x1f31f;二、需求与测试用例、软件错误&#xff0c;软件生…

一旦80%的开发人员都开始利用ChatGPT提升工作效率后,挑战与机遇在哪里?

其实我现在已经开始逐渐开始喜欢上ChatGPT了&#xff0c;上班时间摸摸鱼&#xff0c;和ChatGPT畅谈一下理想&#xff0c;遇见一些不太熟练的代码也懒得去上网查了&#xff0c;直接问一问ChatGPT&#xff0c;然后自己再放置到自己的代码里&#xff0c;改一改&#xff0c;很完美。…

快递出入库管理APP开发 收发快递更方便

网购的盛行让收发快递成为很多人日常生活必不可少的一个环节&#xff0c;对于快递公司来说&#xff0c;每天有那么多的快递&#xff0c;如果没有一个好用的管理系统的话&#xff0c;不仅麻烦还很容易出现纰漏&#xff0c;所以快递出入库管理APP软件就显得很必要了。 快递…

python-imageio库简单使用

目录 imread_v2() get_reader() 使用imageio方法将彩色视频变为黑白视频 相关&#xff1a;python-动图制作及分解_觅远的博客-CSDN博客 imageio是一个用于读取和写入图像及视频数据的库&#xff0c;支持多种格式&#xff0c;且可以使用NumPy数组进行操作。常用方法&#xff…

JS逆向 -- 某平台登录加密分析

一、打开网站&#xff0c;使用账号密码登录 账号&#xff1a;aiyou123.com 密码&#xff1a;123456 二、通过F12抓包&#xff0c;抓到如下数据&#xff0c;发现密码加密了 三、加密结果是32位&#xff0c;首先考虑是md5加密。 四、全局搜索pwd&#xff0c;点击右上角&#xf…

C# 纯text文本字符添加上下角标

工作的需求&#xff0c;需要在GridView列HeaderText中插入带入带有上标和下标的字符串&#xff0c;比如这样的一个字符串&#xff1a;。。 解决办法&#xff1a;使用转义字符加Unicode的NumEntity就可以实现了。定义字符串如下&#xff1a;"O"。其中O为 。 实现&…

Linux系统目录树结构以及解释

FHS标准 Filesystem Hierarchy Standard&#xff08;文件系统层次化标准&#xff09;的缩写&#xff0c;多数Linux版本采用这种文件组织形式&#xff0c;类似于Windows操作系统中c盘的文件目录&#xff0c;FHS采用树形结构组织文件。FHS定义了系统中每个区域的用途、所需要的最…

rk平台调试音频(从驱动到apk)

需要实现的功能&#xff1a; 输入&#xff1a;hdmiin、uvc、mic可以实时切换 输出&#xff1a;耳机和HDMI OUT同时输出声音 这里注意&#xff1a;mic是存在hedset情况&#xff0c;4节耳机&#xff0c;即可输出又可输出同时进行 开发情况&#xff1a; 一、先熟悉大致的Andro…

【24】核心易中期刊推荐——图像处理研究大数据及智能处理研究

🚀🚀🚀NEW!!!核心易中期刊推荐栏目来啦 ~ 📚🍀 核心期刊在国内的应用范围非常广,核心期刊发表论文是国内很多作者晋升的硬性要求,并且在国内属于顶尖论文发表,具有很高的学术价值。在中文核心目录体系中,权威代表有CSSCI、CSCD和北大核心。其中,中文期刊的数…

springboot内嵌tomcat文件上传路径不存在问题原因

错误提示: 临时文件目录被删除,导致文件上传报错,我们使用的是linux系统,10天没有使用,就会被删除 代码: 解决办法: 配置文件中自定义临时文件上传目录 server:port: 9090tomcat:basedir: /crm/tmp 特殊情况: 当我上传小文件的时候可以上传成功,大文件的时候上传失败 猜测可…

利用Linux的corntab定时任务和shell脚本,解决傻妞卡死、发信息没反应、一直卡在即将重启、查询数据异常等问题

利用Linux的corntab定时任务和shell脚本&#xff0c;解决傻妞卡死、数据异常等问题 安装corntab创建shell脚本添加corntab定时任务 原理 定时杀死傻妞进程&#xff0c;并自动重启傻妞 安装corntab Linux crontab是用来定期执行程序的命令。 CentOS安装命令如下 yum -y insta…

【Android -- 开发工具】Source Insight 4.0 安装和使用教程

简介 Source Insight 工具是一款功能强大的代码阅读器&#xff0c;它能使大量的代码产生联系&#xff0c;方便阅读&#xff0c;而且支持各种语言的程序代码。 安装 & 激活 1. 下载 下载地址 直接点击下载即可&#xff0c;我下载的是 4.0 版本。 然后按照步骤安装完成即…

chatGPT给出Python time.sleep()假死(挂起)的解决办法

1. time.sleep()假死&#xff08;挂起&#xff09;的原因与解决办法 最近&#xff0c;使用chatGPT帮着写程序&#xff0c;完成通过API获取天气数据的程序&#xff0c;运行起来后出现了状况&#xff1a;莫名其妙的的假死&#xff08;程序被挂起来&#xff0c;不执行了&#xff…

项目结构如何改造(利用RuoYi-Vue脚手架开发一个健身房会员管理系统,改造项目结构)

项目结构如何改造&#xff08;利用RuoYi-Vue脚手架开发一个健身房会员管理系统&#xff0c;改造项目结构&#xff09; 1. 全局查找替换&#xff08;Ctrl Shift R&#xff09;2. 全局查找替换版本号3. 全局查找替换模块名4. 修改项目名5. ShiftF6 重命名模块6. ShiftF6 重命名…