【问题标题】:Piecewise function Pyomo分段函数 Pyomo
【发布时间】:2020-07-30 13:49:21
【问题描述】:

我想使用分段函数来修改我的 pyomo 模型中的值:

  • 2 -> 1
  • -3 -> 0
  • 5 -> 0.5
  • 0 -> 0

我有一个名为 model.test 的变量,取值 [-3,0,2,5] :

h_change : Size=11, Index=vehicules
    Key : Lower : Value : Upper : Fixed : Stale : Domain
      0 :    -3 :   0.0 :     5 : False : False : Integers
      1 :    -3 :   2.0 :     5 : False : False : Integers
      2 :    -3 :   2.0 :     5 : False : False : Integers
      3 :    -3 :   2.0 :     5 : False : False : Integers
      4 :    -3 :   0.0 :     5 : False : False : Integers
      5 :    -3 :  -3.0 :     5 : False : False : Integers
      6 :    -3 :   0.0 :     5 : False : False : Integers
      7 :    -3 :   0.0 :     5 : False : False : Integers
      8 :    -3 :   0.0 :     5 : False : False : Integers
      9 :    -3 :   0.0 :     5 : False : False : Integers
     10 :    -3 :   5.0 :     5 : False : False : Integers

我使用了下一个分段约束:

model.test = Var(model.vehicules, initialize=0, bounds=(0,1))

DOMAIN_PTS = [-3.,0.,2.,5.]
RANGE_PTS  = [0.,0.,1.,0.5]

model.con = Piecewise(model.vehicules, #Indexation
                        model.test, # Var res
                        model.h_change, #Var observées
                          pw_pts=DOMAIN_PTS,
                          pw_constr_type='EQ',
                          f_rule=RANGE_PTS)

我的变量 model.test 结果是这样的:

test : Size=11, Index=vehicules
    Key : Lower : Value               : Upper : Fixed : Stale : Domain
      0 :     0 :                 0.0 :     1 : False : False :  Reals
      1 :     0 : 0.20000000000000004 :     1 : False : False :  Reals
      2 :     0 : 0.20000000000000004 :     1 : False : False :  Reals
      3 :     0 : 0.20000000000000004 :     1 : False : False :  Reals
      4 :     0 :                 0.0 :     1 : False : False :  Reals
      5 :     0 :                 0.0 :     1 : False : False :  Reals
      6 :     0 :                 0.0 :     1 : False : False :  Reals
      7 :     0 :                 0.0 :     1 : False : False :  Reals
      8 :     0 :                 0.0 :     1 : False : False :  Reals
      9 :     0 :                 0.0 :     1 : False : False :  Reals
     10 :     0 :  0.5000000000000001 :     1 : False : False :  Reals

我不明白为什么我的 2 个值(索引 1、2、3)变成 0.2 而不是 1。

你能帮我理解我的代码有什么问题吗?


更新:


我试过这段代码来测试(来自http://yetanothermathprogrammingconsultant.blogspot.com/2019/02/piecewise-linear-functions-and.html

#
# expected solution X=5, Y=6
#

xdata = [1., 3., 6., 10.]
ydata  = [6.,2.,8.,7.]

from pyomo.core import *

model = ConcreteModel()

model.X = Var(bounds=(1,10))
model.Y = Var(bounds=(0,100))

model.con = Piecewise(model.Y,model.X,
                      pw_pts=xdata,
                      pw_constr_type='EQ',
                      f_rule=ydata,
                      pw_repn='SOS2')

# see what we get for Y when X=5
def con2_rule(model):
    return model.X==5

model.con2 = Constraint(rule=con2_rule)

model.obj = Objective(expr=model.Y, sense=maximize)

但是通过我的求解器 (Couenne) 我得到了

Y=7.600000072980164。

我认为我的求解器存在问题,而不是 PieceWise 代码...

【问题讨论】:

  • 不确定,但是...在上一行代码中,您将 model.test 绑定到 (0, 1)。尝试删除/放松对变量的限制,也许只是 NonNegativeReals
  • 我尝试使用这些边界但没有成功...当没有设置边界和域或仅设置域=NonNegatuceReals 时,我的求解器提前停止而没有解决方案(“此应用程序已请求运行时终止它以一种不寻常的方式。”)。将 bounds=(0,2) 与之前的结果相同(0.2 而不是 1)...
  • 嗯。看起来你正在使用 2 个模型??? modelmodel_3 同时?
  • 对不起,我将编辑我的第一条消息。我只使用一个模型(实际上称为 model_3,但简单地称为模型时更容易理解)
  • 我将在下面删除我的答案,这是偏离轨道的。希望它会增加您获得一个好的解决方案的机会。

标签: python pyomo piecewise


【解决方案1】:

我找到了一种让我的约束起作用的方法:

只需更改pw_repn='SOS2'pw_repn='CC'

【讨论】:

    【解决方案2】:

    尝试使用 cplex 求解器。 我用 CPLEX 求解器运行代码,它给了我相同的结果。

    【讨论】:

    • 正如目前所写,您的答案尚不清楚。请edit 添加其他详细信息,以帮助其他人了解这如何解决所提出的问题。你可以找到更多关于如何写好答案的信息in the help center
    猜你喜欢
    • 2021-08-04
    • 2019-07-10
    • 1970-01-01
    • 2020-02-06
    • 2021-07-29
    • 2017-03-04
    • 2017-02-15
    • 2018-06-18
    • 1970-01-01
    相关资源
    最近更新 更多