数学建模 | 几种非线性表达式线性化的技巧(附Python+Gurobi代码,上)

hello,大家好。各位可点击左下方阅读原文,访问公众号官方店铺。谨防上当受骗,感谢各位支持!如果链接无法访问,公众号后台回复代码商店,即可获取官方店铺最新链接。

Hello,各位小伙伴。前一段时间在实际工作中遇到这样两个问题:

1.在构建的数学模型中,存在两个0-1决策变量相乘的情况,如 x i ∈ { 0 , 1 } x_i \in \left\{ 0,1\right\} xi{0,1} x j ∈ { 0 , 1 } x_j \in \left\{ 0,1\right\} xj{0,1} z i j = x i x j z_{ij} = x_i x_j zij=xixj,那么一个很容易想到的解决方案为如何将 z i j = x i x j z_{ij} = x_i x_j zij=xixj这个非线性表达式线性化处理。

2.在构建的数学模型中,存在1个0-1决策变量和1个连续决策变量相乘的情况,如 x ∈ { 0 , 1 } x \in \left\{ 0,1\right\} x{0,1} y ∈ [ 0 , 20 ] y \in \left[ 0,20 \right] y[0,20] z = x y z = x y z=xy,这个问题也是同样的想法,如何将 z = x y z = xy z=xy这个非线性表达式线性化处理。

上述两个问题,应该是在构建数学模型过程中,经常会遇到的问题。但是本着想寻找更多非线性表达式线性化技巧的精神,通过查阅网上优质资料以及相关书籍,共整理了10个常见的非线性表达式线性化技巧。

  1. 分段函数
  2. 绝对值函数
  3. MaxMin/MinMax函数
  4. 逻辑或
  5. MaxMax/MinMin函数
  6. 两个0-1变量的乘积形式
  7. 1个0-1变量和1个连续变量的乘积形式
  8. 分式目标函数形式
  9. Max/Min函数
  10. 混合整数

线性化的主要手段其实就两点:一是引入0-1变量,二是引入很大的整数M

https://zhuanlan.zhihu.com/p/552076713

本次推文只讲解分段函数、绝对值函数、MaxMin/MinMax函数、两个0-1变量的乘积形式、1个0-1变量和1个连续变量的乘积形式5个线性化技巧。

目录

  1. 分段函数
  2. 绝对值函数
  3. MaxMin/MinMax函数
  4. 两个0-1变量的乘积形式
  5. 1个0-1变量和1个连续变量的乘积形式

分段函数

分段函数 f ( x ) f(x) f(x)的数学表达式如下:
f ( x ) = { f 1 ( x ) 0 < x ≤ a f 2 ( x ) a < x ≤ b f 3 ( x ) b < x ≤ c f(x)= \begin{cases}f_1(x) & 0<x \leq a \\ f_2(x) & a<x \leq b \\ f_3(x) & b<x \leq c\end{cases} f(x)= f1(x)f2(x)f3(x)0<xaa<xbb<xc
如果要对分段函数 f ( x ) f(x) f(x)进行线性化处理,则需要引入0-1辅助变量 y y y和一个很大的正整数 M M M
f ( x ) = f 1 ( x ) y 1 + f 2 ( x ) y 2 + f 3 ( x ) y 3  s.t.  0 < x ≤ M ( 1 − y 1 ) + a a y 2 < x ≤ M ( 1 − y 2 ) + b b y 3 < x ≤ M ( 1 − y 3 ) + c y 1 , y 2 , y 3 ∈ { 0 , 1 } y 1 + y 2 + y 3 = 1 \begin{gathered} f(x)=f_1(x) y_1+f_2(x) y_2+f_3(x) y_3 \\ \text { s.t. } \quad 0<x \leq M\left(1-y_1\right)+a \\ ay_2<x \leq M\left(1-y_2\right)+b \\ by_3<x \leq M\left(1-y_3\right)+c \\ y_1, y_2, y_3 \in\{0,1\} \\ y_1+y_2+y_3=1 \end{gathered} f(x)=f1(x)y1+f2(x)y2+f3(x)y3 s.t. 0<xM(1y1)+aay2<xM(1y2)+bby3<xM(1y3)+cy1,y2,y3{0,1}y1+y2+y3=1

【举例】
min ⁡ f ( x ) f ( x ) = { − x + 2 0 < x ≤ 1 − 1 2 x + 5 4 1 < x ≤ 3 x − 3 3 < x ≤ 5  s.t.  x > 0 \begin{gathered} \min f(x) \\ f(x)=\left\{\begin{array}{cc} -x+2 & 0<x \leq 1 \\ -\frac{1}{2} x+\frac{5}{4} & 1<x \leq 3 \\ x-3 & 3<x \leq 5 \end{array}\right. \\ \text { s.t. } x>0 \end{gathered} minf(x)f(x)= x+221x+45x30<x11<x33<x5 s.t. x>0
将分段函数 f ( x ) f(x) f(x)进行线性化处理,需要引入0-1辅助变量 y y y和一个很大的正整数 M M M,线性化处理后的模型如下:
min ⁡ f ( x ) = ( − x + 2 ) × y 1 + ( − 1 2 x + 5 4 ) × y 2 + ( x − 3 ) × y 3  s.t.  0 < x ≤ M ( 1 − y 1 ) + 1 y 2 < x ≤ M ( 1 − y 2 ) + 3 3 y 3 < x ≤ M ( 1 − y 3 ) + 5 y 1 + y 2 + y 3 = 1 y 1 , y 2 , y 3 ∈ { 0 , 1 } \begin{gathered} \min f(x)=(-x+2) \times y_1+\left(-\frac{1}{2} x+\frac{5}{4}\right) \times y_2+(x-3) \times y_3 \\ \text { s.t. } 0<x \leq M\left(1-y_1\right)+1 \\ y_2<x \leq M\left(1-y_2\right)+3 \\ 3 y_3<x \leq M\left(1-y_3\right)+5 \\ y_1+y_2+y_3=1 \\ y_1, y_2, y_3 \in\{0,1\} \end{gathered} minf(x)=(x+2)×y1+(21x+45)×y2+(x3)×y3 s.t. 0<xM(1y1)+1y2<xM(1y2)+33y3<xM(1y3)+5y1+y2+y3=1y1,y2,y3{0,1}
很明显,当 x = 3 x=3 x=3时, f ( x ) f(x) f(x)取最小值 − 0.25 -0.25 0.25

现在我们用python+gurobi对上述模型进行求解,代码如下:

from gurobipy import *

model = Model('non-linear model')
x = model.addVar(lb=0, ub=GRB.INFINITY, vtype=GRB.CONTINUOUS, name='x')
y1 = model.addVar(lb=0, ub=1, vtype=GRB.BINARY, name='y1')
y2 = model.addVar(lb=0, ub=1, vtype=GRB.BINARY, name='y2')
y3 = model.addVar(lb=0, ub=1, vtype=GRB.BINARY, name='y3')

bigM = 10000
epsilon = 1e-5
model.setObjective((-1 * x + 2) * y1 + (-0.5 * x + 1.25) * y2 + (x - 3) * y3, GRB.MINIMIZE)

model.addConstr(x <= bigM * (1 - y1) + 1, name='c1')
model.addConstr(x <= bigM * (1 - y2) + 3, name='c2')
model.addConstr(x - y2 >= epsilon, name='c2')
model.addConstr(x - 3 * y3 >= epsilon, name='c3')
model.addConstr(x <= bigM * (1 - y3) + 5, name='c3')
model.addConstr(y1 + y2 + y3 == 1, name='c4')

model.setParam(GRB.Param.LogFile, 'gurobi.log')

modelName = 'nlTol1.lp'
model.write(modelName)
model.optimize()
solName = 'nlTol1.sol'
model.write(solName)

print('x:', x.x)
print('y1:', y1.x)
print('y2:', y2.x)
print('y3:', y3.x)

求解结果为:

Optimal solution found (tolerance 1.00e-04)
Best objective -2.500000000000e-01, best bound -2.500000000000e-01, gap 0.0000%
x: 3.0
y1: 0.0
y2: 1.0
y3: 0.0

该结果与当 x = 3 x=3 x=3时, f ( x ) f(x) f(x)取最小值 − 0.25 -0.25 0.25的结果保持一致。


绝对值函数

将如下数学模型进行线性化处理:
min ⁡ ∑ i c i ∣ x i ∣ A x = b x i  free,  c i ≥ 0 , ∀ i \begin{aligned} & \min \sum_i c_i\left|x_i\right| \\ & A x=b \\ & x_i \text { free, } c_i \geq 0, \forall i \end{aligned} minicixiAx=bxi free, ci0,i
**线性化方法1:**引入 y i y_i yi替代 ∣ x i ∣ \left|x_i\right| xi
y i = ∣ x i ∣ ↓ y i ≥ x i , y i ≥ − x i ↓ min ⁡ ∑ i c i ∣ y i ∣ A x = b y i ≥ x i , y i ≥ − x i x i  free,  c i ≥ 0 \begin{gathered} y_i=\left|x_i\right| \\ \downarrow \\ y_i \geq x_i, \quad y_i \geq-x_i \\ \downarrow \\ \begin{aligned} & \min \sum_i c_i\left|y_i\right| \\ & A x=b \\ & y_i \geq x_i, y_i \geq-x_i \\ & x_i \text { free, } c_i \geq 0 \end{aligned} \end{gathered} yi=xiyixi,yiximiniciyiAx=byixi,yixixi free, ci0
但是使用 y i y_i yi替代 ∣ x i ∣ \left|x_i\right| xi这种方法可能会导致最终求解结果存在 y i ≠ ∣ x i ∣ y_i \neq\left|x_i\right| yi=xi的情况,关于这种情况具体的解决方案详见非线性优化 | 非线性问题线性化以及求解的详细案例及Python+Gurobi求解

线性化方法2:引入 u i u_i ui v i v_i vi替代 ∣ x i ∣ \left|x_i\right| xi

∀ x , ∃ u , v ≥ 0 , 使得  x = u − v , ∣ x ∣ = u + v , 其中  u = ∣ x ∣ + x 2 , v = ∣ x ∣ − x 2 \forall x, \exists u, v \geq 0 \text {, 使得 } x=u-v,|x|=u+v \text {, 其中 } u=\frac{|x|+x}{2}, v=\frac{|x|-x}{2} x,u,v0使得 x=uv,x=u+v其中 u=2x+x,v=2xx

因此原模型线性化为如下的模型
min ⁡ ∑ i c i ( u i + v i ) A ( u − v ) = b u , v ≥ 0 \begin{aligned} & \min \sum_i c_i\left(u_i+v_i\right) \\ & A(u-v)=b \\ & u, v \geq 0 \end{aligned} minici(ui+vi)A(uv)=bu,v0
【举例】
min ⁡ ∣ x 1 ∣ + ∣ x 2 ∣  s.t.  x 1 + x 2 = 0 \begin{aligned} & \min \left|x_1\right|+\left|x_2\right| \\ & \text { s.t. } x_1+x_2=0 \end{aligned} minx1+x2 s.t. x1+x2=0
此处,我们使用方法2对该模型进行线性化处理:

引入 u 1 , v 1 , u 2 , v 2 u_1,v_1,u_2,v_2 u1,v1,u2,v2分别替代 ∣ x 1 ∣ \left|x_1\right| x1 ∣ x 2 ∣ \left|x_2\right| x2,则 x 1 = u 1 − v 1 , ∣ x 1 ∣ = u 1 + v 1 , x 2 = u 2 − v 2 , ∣ x 2 ∣ = u 2 + v 2 x_1=u_1-v_1,\left|x_1\right|=u_1+v_1,x_2=u_2-v_2,\left|x_2\right|=u_2+v_2 x1=u1v1,x1=u1+v1,x2=u2v2,x2=u2+v2,且 u 1 ≥ 0 , v 1 ≥ 0 , u 2 ≥ 0 , v 2 ≥ 0 u_1 \geq 0,v_1 \geq 0,u_2 \geq 0,v_2 \geq 0 u10,v10,u20,v20

则原模型转化为:
min ⁡ u 1 + v 1 + u 2 + v 2  s.t.  u 1 − v 1 + u 2 − v 2 = 0 u 1 ≥ 0 , u 2 ≥ 0 v 1 ≥ 0 , v 2 ≥ 0 \begin{array}{ll} \min & u_1+v_1+u_2+v_2 \\ \text { s.t. } & u_1-v_1+u_2-v_2=0 \\ & u_1 \geq 0, u_2 \geq 0 \\ & v_1 \geq 0, v_2 \geq 0 \end{array} min s.t. u1+v1+u2+v2u1v1+u2v2=0u10,u20v10,v20
很明显,当 x 1 = 0 x_1=0 x1=0 x 2 = 0 x_2=0 x2=0时, f ( x ) f(x) f(x)取最小值 0 0 0

python+gurobi对上述线性模型进行求解,代码如下:

from gurobipy import *

model = Model('non-linear model')
u1 = model.addVar(lb=0, ub=GRB.INFINITY, vtype=GRB.CONTINUOUS, name='u1')
u2 = model.addVar(lb=0, ub=GRB.INFINITY, vtype=GRB.CONTINUOUS, name='u2')
v1 = model.addVar(lb=0, ub=GRB.INFINITY, vtype=GRB.CONTINUOUS, name='v1')
v2 = model.addVar(lb=0, ub=GRB.INFINITY, vtype=GRB.CONTINUOUS, name='v2')

model.setObjective(u1+v1+u2+v2, GRB.MINIMIZE)

model.addConstr(u1-v1+u2-v2 == 0, name='c1')

model.setParam(GRB.Param.LogFile, 'gurobi.log')

modelName = 'nlTol2.lp'
model.write(modelName)
model.optimize()
solName = 'nlTol2.sol'
model.write(solName)

print('u1:', u1.x)
print('v1:', v1.x)
print('u2:', u2.x)
print('v2:', v2.x)

求解结果为:

Optimal objective  0.000000000e+00
u1: 0.0
v1: 0.0
u2: 0.0
v2: 0.0

该结果与当 x 1 = 0 x_1=0 x1=0 x 2 = 0 x_2=0 x2=0时, f ( x ) f(x) f(x)取最小值 0 0 0的结果保持一致。

MaxMin/MinMax函数

max ⁡ ( min ⁡ k ∈ K ∑ i c k i x i ) \max \left(\min _{k \in K} \sum_i c_{k i} x_i\right) max(minkKickixi)函数线性化后的表达式如下:
max ⁡ z z ≤ ∑ i c k i x i , ∀ k ∈ K \begin{gathered} \max z \\ z \leq \sum_i c_{k i} x_i, \quad \forall k \in K \end{gathered} maxzzickixi,kK
该形式下的线性化方法是:用 z z z替代 min ⁡ k ∈ K ∑ i c k i x i \min _{k \in K} \sum_i c_{k i} x_i minkKickixi函数,这样 z ≤ ∑ i c k i x i , ∀ k ∈ K z \leq \sum_i c_{k i} x_i,\forall k \in K zickixi,kK,又由目标函数是取最大的 z z z,从而限制住不 z z z会无限小下去,而只会取满足条件的 z z z

同理,将 min ⁡ ( max ⁡ k ∈ K ∑ i c k i x i ) \min \left(\max _{k \in K} \sum_i c_{k i} x_i\right) min(maxkKickixi)函数线性化后的表达式如下:
min ⁡ z z ≥ ∑ i c k i x i , ∀ k ∈ K \begin{gathered} \min z \\ z \geq \sum_i c_{k i} x_i, \quad \forall k \in K \end{gathered} minzzickixi,kK
【举例】

max ⁡ ( min ⁡ x + 2 y + 10 , 3 x + y + 1 ) \max (\min x+2 y+10,3 x+y+1) max(minx+2y+10,3x+y+1)函数线性化后的表达式如下:
max ⁡ z z ≤ x + 2 y + 10 z ≤ 3 x + y + 1 \begin{gathered} \max z \\ z \leq x+2 y+10 \\ z \leq 3 x+y+1 \end{gathered} maxzzx+2y+10z3x+y+1

两个0-1变量的乘积形式

关于这部分内容详见【教学视频】优化 | 线性化:两个0-1变量相乘的线性化

1个0-1变量和1个连续变量的乘积形式

关于这部分内容详见【教学视频】优化 | 线性化(2):连续变量 * 0-1变量的线性化

参考

  1. 《数学优化问题分类及求解方法介绍》-尹明强
  2. https://zhuanlan.zhihu.com/p/552076713
  3. https://zhuanlan.zhihu.com/p/63204658
  4. https://blog.csdn.net/robert_chen1988/article/details/114482099
  5. 【教学视频】优化 | 线性化:两个0-1变量相乘的线性化
  6. 【教学视频】优化 | 线性化(2):连续变量 * 0-1变量的线性化
  7. 非线性优化 | 非线性问题线性化以及求解的详细案例及Python+Gurobi求解

想快速入门智能优化算法的小伙伴可以阅读我们的书籍,本书对算法的讲解详细易懂,对代码的注释也十分完备,想要入手此书的小伙伴可以抓紧入手哦!

京东自营购买链接:

https://item.jd.com/13422442.html

当当自营购买链接

http://product.dangdang.com/29301483.html

OK,今天就到这里啦。我们已经推出粉丝QQ交流群,各位小伙伴赶快加入吧!!!


咱们下期再见

近期你可能错过了的好文章

新书上架 | 《MATLAB智能优化算法:从写代码到算法思想》

算法自学 | 优化算法书籍+代码+网站+推文一站式合集(上)

优化算法 | 灰狼优化算法(文末有福利)

优化算法 | 鲸鱼优化算法

遗传算法(GA)求解带时间窗的车辆路径(VRPTW)问题MATLAB代码

粒子群优化算法(PSO)求解带时间窗的车辆路径问题(VRPTW)MATLAB代码

知乎 | bilibili | CSDN:随心390

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值