Pyomo调用MindtPy求解优化模型未返回正确最优解问题咨询
问题原因
- 缺失MindtPy必要配置:MindtPy属于MINLP分解求解器,必须显式指定MIP求解器(如cbc、gurobi)和NLP求解器(如ipopt),你代码中未传递这两个参数,默认求解器组合处理双线性项+无界变量时出现数值异常,从返回结果可以看到下界(7.49e-9)大于上界(-5.25e-9),属于典型的数值容差错误,导致求解器误将y=0的次优解判定为全局最优。
- 变量x无上限导致分支偏差:你定义的x为无上限非负整数,虽然约束x*y<=10,但求解器生成外逼近割时,无界变量会导致割面计算偏差,初始化阶段优先探索y=0的可行域分支,未遍历y=1的分支。
修复方案
方案1:补全MindtPy配置,给x加合理上限
因为y最多取1,约束x*y<=10等价于x最大可取10,给x加上界后配合指定求解器即可得到正确结果:
import pyomo.environ as pyo model = pyo.ConcreteModel() model.x = pyo.Var(domain=pyo.NonNegativeIntegers, bounds=(0, 10)) model.y = pyo.Var(domain=pyo.Binary) model.constraint = pyo.Constraint(expr = model.x * model.y <= 10) model.objective = pyo.Objective(expr = model.x * model.y - model.y, sense = pyo.maximize) # 显式指定MIP和NLP求解器,可根据你本地安装的求解器替换 res = pyo.SolverFactory('mindtpy').solve(model, mip_solver='cbc', nlp_solver='ipopt')
方案2:线性化双线性项,改用纯整数规划求解
y为二进制变量的场景下,双线性项x*y可以通过大M法线性化,彻底避免非线性求解的稳定性问题,求解效率更高:
import pyomo.environ as pyo M = 10 # x的最大可能取值,作为大M参数 model = pyo.ConcreteModel() model.x = pyo.Var(domain=pyo.NonNegativeIntegers, bounds=(0, M)) model.y = pyo.Var(domain=pyo.Binary) model.xy = pyo.Var(domain=pyo.NonNegativeIntegers, bounds=(0, M)) # 替代x*y的中间变量 # 双线性项线性化约束 model.lin_cons1 = pyo.Constraint(expr = model.xy <= model.x) model.lin_cons2 = pyo.Constraint(expr = model.xy <= M * model.y) model.lin_cons3 = pyo.Constraint(expr = model.xy >= model.x - M * (1 - model.y)) model.constraint = pyo.Constraint(expr = model.xy <= 10) model.objective = pyo.Objective(expr = model.xy - model.y, sense = pyo.maximize) # 直接用普通MIP求解器即可得到最优解 res = pyo.SolverFactory('cbc').solve(model)
两种方案最终都会得到最优解x=10, y=1,目标值为9。
内容的提问来源于stack exchange,提问作者Seon
相关产品推荐
相关产品推荐

