【问题标题】:Simple quadratic problem in Gurobi not producing optimal result?Gurobi 中的简单二次问题没有产生最佳结果?
【发布时间】:2021-11-23 17:10:46
【问题描述】:

我无法理解为什么下面的代码没有产生最佳结果。我正在尝试创建一个阶跃函数,但这显然不能作为模型的解决方案值。Z 不是指定的范围点之一。

非常感谢任何有助于理解/纠正此问题的帮助。

我要做什么

最大化Z * X,受制于:

          / 20.5  , X <= 5
  Z(X)  = | 10    , 5 <= X <= 10
          \ 9     , 10 <= X <= 11

更好的是,我想在以下条件下求解(断点不相交):

          / 20.5  , X <= 5
  Z(X)  = | 10    , 5 < X <= 10
          \ 9     , 10 < X <= 11

其中XZ 是浮点数。

我希望 X5Z20.5,但是模型结果是 7.3715.53

代码

from pyomo.core import *

# Break points for step-function
DOMAIN_PTS = [5., 10., 11.]
RANGE_PTS = [20.5, 10., 9.]

# Define model and variables
model = ConcreteModel()
model.X = Var(bounds=(5,11))
model.Z = Var()

# Set piecewise constraint
model.con = Piecewise(model.Z,model.X, 
                      pw_pts=DOMAIN_PTS ,
                      pw_constr_type='EQ',
                      f_rule=RANGE_PTS,
                      force_pw=True,
                      pw_repn='SOS2') 

model.obj = Objective(expr= model.Z * model.X, sense=maximize)
opt = SolverFactory('gurobi')
opt.options['NonConvex'] = 2
obj_val = opt.solve(model)

print(value(model.X))
print(value(model.Z))
print(model.obj())

【问题讨论】:

  • 正如 pybegginer 的回答已经提到的那样,您想要建模分段常数函数,而不是分段线性函数。有关建模技巧,请参阅 here

标签: python pyomo gurobi


【解决方案1】:

Pyomo 中的Piecewise 旨在在另一个变量给出的某些界限之间进行线性插值。这意味着,如果您在尝试时给出给定的界限,那么您的插值 as this(对于这样一个糟糕的图表感到抱歉)这基本上意味着您在 x=5 和 x=10 之间放置一条线Z= 31 - 2.1X,以及 10 到 11 之间的另一行。事实上,Gurobi 正在计算最佳结果,因为 x 它是 NonNegativeReal 并且在这样的行中 Z= 31 - 2.1Xx=7.37 给出结果 Z=15.53

现在,我知道您想要一个阶梯函数而不是插值,类似于 to this(再次抱歉这么糟糕的图表),那么您需要更改您的 DOMAIN_PTSRANGE_PTS 以便正确建模你想要的

# Break points for step-function
DOMAIN_PTS = [5.,5., 10., 10.,11.]
RANGE_PTS = [20.5,10., 10., 9., 9.]

这样,您在f(x)=20.5: 5&lt;=x&lt;=10 等之间进行插值。

【讨论】:

  • 啊,我明白了 - 我误解了断点的定义。感谢您的帮助@pybeginner
【解决方案2】:

我会从不分段线性化z,但总是z*x。如果您只有z 的分段线性表达式,那么z*x 是非线性的(并且以一种令人讨厌的方式)。但是,如果您为z*x 写下分段线性表达式,那么整个事情就会变成线性的。请注意,分段函数中的不连续性需要注意。

在将其传递给求解器之前,从数学上理解您所写的内容非常重要。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-07-02
    • 1970-01-01
    • 2015-04-20
    • 2015-06-23
    相关资源
    最近更新 更多