数学模型tricks | 大M法线性化注意事项

本文探讨了使用大M法线性化二次项时遇到的问题及解决方法。通过实例展示了大M取值不当可能导致的错误,并指出大M应适中,既不能太小影响线性化效果,也不能太大引起数值计算误差。此外,还提到了Gurobi求解时的精度设置对结果的影响,以及直接使用求解器自动线性化的策略。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

数学模型tricks | 大M法线性化注意事项



问题

有如下二次项:
g x gx gx
其中
g ∈ { 0 , 1 } , − 10 ≤ x ≤ 0 g \in \{0,1\},-10 \leq x \leq 0 g{0,1},10x0
用大M法线性化
y = g x y = gx y=gx,转化为 y ≥ x , y ≥ − M g , y ≤ x + M ( 1 − g ) y \geq x,y \geq -Mg,y \leq x + M(1-g) yxyMgyx+M(1g)
即: g = 1 g =1 g=1时, y = x y=x y=x g = 0 g =0 g=0时, y = 0 y=0 y=0

为了检验大M法的效果,用Gurobi求解下面的问题
m i n x y ≥ x y ≥ − M g y ≤ x + M ( 1 − g ) g ∈ { 0 , 1 } − 10 ≤ y ≤ 0 − 10 ≤ x ≤ 0 min \quad x\\ y \geq x\\ y \geq -Mg\\ y \leq x + M(1-g)\\ g \in \{0,1\}\\ -10\leq y \leq 0\\ -10 \leq x \leq 0 minxyxyMgyx+M(1g)g{0,1}10y010x0

from gurobipy import *
m= Model()
M = GRB.INFINITY
x = m.addVar(lb = -10,ub=0,vtype=GRB.CONTINUOUS,name='miu')
y = m.addVar(lb = -10,ub=0,vtype=GRB.CONTINUOUS,name='xi')
g = m.addVar(vtype=GRB.BINARY,name='g')

m.setObjective(x,GRB.MINIMIZE)

m.addConstr(y >= x)
m.addConstr(y >= -M * g)
m.addConstr(y <= x + M * (1 - g))
m.optimize()
m.write('test.lp')

结果最优解居然是 x = − 10 , g = 1 , y = 0 x=-10,g=1, y=0 x=10g=1,y=0,而我们知道 g = 1 g =1 g=1时,肯定满足 y = x y=x y=x

错误根源

找了很久,发现是大M取值的问题,导致了数值计算中出现错误。 大M取GRB.INFINITY太大了。
解决方案:

M = GRB.INFINITY 改为 M = 10e6

结果就正确了

经测试,发现当满足 M ≤ 10 e 16 M\leq 10e16 M10e16,结果正确,当 M ≥ 10 e 17 M \geq 10e17 M10e17就会出现上面的错误了。


总结

1.综上

在和运筹优化群里大佬的讨论后总结如下:
大M不能太小,若太小则不能保证线性化后不等式的方向,因此无法起到线性化的作用;也不能太大,会导致数值计算上的问题。
大M如果有物理意义,根据物理意义来取值越小越好;否则一般取值上,比参数多一两个数量级就好。

2.大M的用法详细介绍

这个网站对大M的用法介绍比较详细:
https://yalmip.github.io/tutorial/bigmandconvexhulls
在这里插入图片描述

3.大M取值太小引发的错误

在另一篇中记录了大M取的太小引起的错误:
[两阶段鲁棒优化 | Biilinear 项的线性化]
(https://blog.csdn.net/m0_46357737/article/details/126117901?spm=1001.2014.3001.5501)

4.Gurobi求解时精度引起的错误

用gurobi求大M法线性化 B i n a r y ∗ C o n t i n u o u s Binary*Continuous BinaryContinuous后的模型,发现结果不对。
检查了很久,后来发现加上

m.setParam('IntegralityFocus',1)

之后结果才正确。精度也会有影响。

5.偷懒的解决方法

直接把带 B i n a r y ∗ C o n t i n u o u s Binary*Continuous BinaryContinuous项的约束扔给Gurobi,他会自动线性化,而且有时候效果比你手动线性化更好。

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值