0
点赞
收藏
分享

微信扫一扫

优化 | 线性化:含绝对值的线性化

司马吹风 2022-02-25 阅读 174

优化 | 线性化:含绝对值的线性化

作者:刘兴禄, 清华大学

清华-伯克利深圳学院,博士在读

在这里插入图片描述

非线性整数规划模型

考虑下面的非线性整数规划

max ⁡     2 ∣ x 1 ∣ + ∣ x 2 ∣ s . t .     ∣ x 1 ∣ + 2 ∣ x 2 ∣ ⩽ 8 − 5 ⩽ x 1 , x 2 ⩽ 5 \begin{aligned} \max \quad \,\,\,& 2|x_1| + |x_2| \\ s.t. \quad \,\,\,& |x_1| + 2|x_2| \leqslant 8 \\ & -5 \leqslant x_1, x_2 \leqslant 5 \end{aligned} maxs.t.2x1+x2x1+2x285x1,x25

Gurobi求解代码

from gurobipy import * 
model = Model('non-linear model')
x1 = model.addVar(lb=-5, ub=5, vtype=GRB.CONTINUOUS, name='x1')
x2 = model.addVar(lb=-5, ub=5, vtype=GRB.CONTINUOUS, name='x2')
x1_abs = model.addVar(lb=0, ub=5, vtype=GRB.CONTINUOUS, name='x1_abs')
x2_abs = model.addVar(lb=0, ub=5, vtype=GRB.CONTINUOUS, name='x2_abs')

model.setObjective(2 * x1_abs  + x2_abs, GRB.MAXIMIZE)
model.addConstr(x1_abs + 2*x2_abs <= 8)
model.addGenConstrAbs(x1_abs, x1)
model.addGenConstrAbs(x2_abs, x2)

model.optimize() 

print('x1:', x1.x)
print('x2:', x2.x)
print('x1_abs:', x1_abs.x)
print('x2_abs:', x2_abs.x)

求解结果

Solution count 1: 11.5 

Optimal solution found (tolerance 1.00e-04)
Best objective 1.150000000000e+01, best bound 1.150000000000e+01, gap 0.0000%
x1: 5.0
x2: 1.5
x1_abs: 5.0
x2_abs: 1.5

绝对值的线性化技巧

这个比较容易理解,例如 x i = − 0.5 x_i = -0.5 xi=0.5, 则 x i + = 0 , x i − = 0.5 x_i^{+} = 0, x_i^{-} = 0.5 xi+=0,xi=0.5, 因此有
x i = x i + − x i − = 0 − 0.5 = − 0.5 x_i = x_i^{+} - x_i^{-} = 0 - 0.5 = -0.5 xi=xi+xi=00.5=0.5
∣ x i ∣ = x i + + x i − = 0 + 0.5 = 0.5 |x_i| = x_i^{+} + x_i^{-} = 0 + 0.5 = 0.5 xi=xi++xi=0+0.5=0.5

利用上面的技巧进行线性化

  • 我们根据

得到,原模型可以线性化为

max ⁡     2 ( x 1 + + x 1 − ) + ( x 2 + + x 2 − ) s . t .     ( x 1 + + x 1 − ) + 2 ( x 2 + + x 2 − ) ⩽ 8 x 1 = x 1 + − x 1 − x 2 = x 2 + − x 2 − x 1 abs = x 1 + + x 1 − x 2 abs = x 2 + + x 2 − x 1 abs ⩾ x 1 x 1 abs ⩾ − x 1 x 2 abs ⩾ x 2 x 2 abs ⩾ − x 2 − 5 ⩽ x 1 , x 2 ⩽ 5 0 ⩽ x i + , x i − , x i abs ⩽ 5 , ∀ i = 1 , 2 \begin{aligned} \max \quad \,\,\,& 2(x_1^{+} + x_1^{-}) + (x_2^{+} + x_2^{-}) \\ s.t. \quad \,\,\,& (x_1^{+} + x_1^{-}) + 2(x_2^{+} + x_2^{-}) \leqslant 8 \\ & x_1 = x_1^{+} - x_1^{-} \\ & x_2 = x_2^{+} - x_2^{-} \\ & x_1^{\text{abs}} = x_1^{+} + x_1^{-} \\ & x_2^{\text{abs}} = x_2^{+} + x_2^{-} \\ & x_1^{\text{abs}} \geqslant x_1 \\ & x_1^{\text{abs}} \geqslant -x_1 \\ & x_2^{\text{abs}} \geqslant x_2 \\ & x_2^{\text{abs}} \geqslant -x_2 \\ & -5 \leqslant x_1, x_2 \leqslant 5 \\ & 0 \leqslant x_i^{+}, x_i^{-}, x_i^{\text{abs}}\leqslant 5, \forall i = 1, 2 \end{aligned} maxs.t.2(x1++x1)+(x2++x2)(x1++x1)+2(x2++x2)8x1=x1+x1x2=x2+x2x1abs=x1++x1x2abs=x2++x2x1absx1x1absx1x2absx2x2absx25x1,x250xi+,xi,xiabs5,i=1,2

下面我们用代码进行验证。

from gurobipy import * 
model = Model('non-linear model')
x1 = model.addVar(lb=-5, ub=5, vtype=GRB.CONTINUOUS, name='x1')
x2 = model.addVar(lb=-5, ub=5, vtype=GRB.CONTINUOUS, name='x2')
x1_pos_abs = model.addVar(lb=0, ub=5, vtype=GRB.CONTINUOUS, name='x1_pos_abs')
x1_neg_abs = model.addVar(lb=0, ub=5, vtype=GRB.CONTINUOUS, name='x1_neg_abs')
x2_pos_abs = model.addVar(lb=0, ub=5, vtype=GRB.CONTINUOUS, name='x2_pos_abs')
x2_neg_abs = model.addVar(lb=0, ub=5, vtype=GRB.CONTINUOUS, name='x2_neg_abs')
x1_abs = model.addVar(lb=0, ub=5, vtype=GRB.CONTINUOUS, name='x1_abs')
x2_abs = model.addVar(lb=0, ub=5, vtype=GRB.CONTINUOUS, name='x2_abs')

model.setObjective(2*(x1_pos_abs + x1_neg_abs) + (x2_pos_abs + x2_neg_abs), GRB.MAXIMIZE) 
model.addConstr((x1_pos_abs + x1_neg_abs) + 2*(x2_pos_abs + x2_neg_abs) <= 8)
model.addConstr(x1 == x1_pos_abs - x1_neg_abs)
model.addConstr(x2 == x2_pos_abs - x2_neg_abs)
model.addConstr(x1_abs == x1_pos_abs + x1_neg_abs)
model.addConstr(x2_abs == x2_pos_abs + x2_neg_abs)
model.addConstr(x1_abs >= x1)
model.addConstr(x1_abs >= -x1) 
model.addConstr(x2_abs >= x2)
model.addConstr(x2_abs >= -x2) 

model.optimize() 


print('x1:', x1.x) 
print('x2:', x2.x)
print('x1_pos_abs:', x1_pos_abs.x) 
print('x1_neg_abs:', x1_neg_abs.x)
print('x2_pos_abs:', x2_pos_abs.x) 
print('x2_neg_abs:', x2_neg_abs.x)

求解结果为

Iteration    Objective       Primal Inf.    Dual Inf.      Time
       0    1.6000000e+01   3.000000e+00   0.000000e+00      0s
       2    1.1500000e+01   0.000000e+00   0.000000e+00      0s

Solved in 2 iterations and 0.01 seconds
Optimal objective  1.150000000e+01
x1: 5.0
x2: 1.5
x1_pos_abs: 5.0
x1_neg_abs: 0.0
x2_pos_abs: 1.5
x2_neg_abs: 0.0

可见结果是一致的。

总结

含有绝对值形式的线性化。


在这里插入图片描述

公众号往期推文如下

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

举报

相关推荐

0 条评论