分段pyomo优化问题中的关联变量

2024-09-29 19:35:47 发布

您现在位置:Python中文网/ 问答频道 /正文

我正在努力解决成本优化问题中的“关联”变量。总的来说,我有四个变量:varX1varX2varY1varY2,它们以以下方式配对:

if 0 <= varX1 < 1 then varY1 = 0
if 1 <= varX1 <= 6 then varY1 = 1

if 0 <= varX2 < 1 then varY2 = 0 
if 1 <= varX2 <= 5 then varY2 = 1 

我尝试使用pyomos分段建模varX1和varY1as well asvarX2andvarY2`的关系,尝试从https://github.com/Pyomo/pyomo/blob/main/examples/pyomo/piecewise/step.py重新创建示例

完整型号代码为:

import pyomo.environ as po

costsX1 = 4
costsX2 = 6

costsY1 = 2
costsY2 = 1

a1 = 4
a2 = 3

model = po.ConcreteModel()

model.VarX1 = po.Var(bounds=(0,6))
model.VarX2 = po.Var(bounds=(0,5))

model.VarY1 = po.Var(within=po.Binary)
model.VarY2 = po.Var(within=po.Binary)

model.cons1 = po.Constraint(expr=model.VarX1+model.VarX2==5)
model.cons2 = po.Constraint(expr=a1*model.VarY1+ a2*model.VarY2>=3)

model.obj = po.Objective(expr=costsX1*model.VarX1+costsY1*a1*model.VarY1+costsX2*model.VarX2+costsY2*a2*model.VarY2,
                         sense=po.minimize)

DOMAIN_PTS_X1 = [0, 1, 1, 6]
RANGE_PTS_Y1  = [0, 0, 1, 1]

DOMAIN_PTS_X2 = [0, 1, 1, 5]
RANGE_PTS_Y2  = [0, 0, 1, 1]

model.piece1 = po.Piecewise(model.VarX1, model.VarY1,
                            pw_pts=DOMAIN_PTS_X1,
                            pw_constr_type='LB',
                            f_rule=RANGE_PTS_Y1,
                            pw_repn='INC')

model.piece2 = po.Piecewise(model.VarX2, model.VarY2,
                            pw_pts=DOMAIN_PTS_X2,
                            pw_constr_type='LB',
                            f_rule=RANGE_PTS_Y2,
                            pw_repn='INC')

opt = po.SolverFactory('cbc')
result_obj = opt.solve(model, tee=True)

model.pprint()

我得到以下结果

4 Var Declarations
    VarX1 : Size=1, Index=None
        Key  : Lower : Value : Upper : Fixed : Stale : Domain
        None :     0 :   5.0 :     6 : False : False :  Reals
    VarX2 : Size=1, Index=None
        Key  : Lower : Value : Upper : Fixed : Stale : Domain
        None :     0 :   0.0 :     5 : False : False :  Reals
    VarY1 : Size=1, Index=None
        Key  : Lower : Value : Upper : Fixed : Stale : Domain
        None :     0 :   0.0 :     1 : False : False : Binary
    VarY2 : Size=1, Index=None
        Key  : Lower : Value : Upper : Fixed : Stale : Domain
        None :     0 :   1.0 :     1 : False : False : Binary

正如我们所看到的,不存在varX1varY1的配对

有人能帮我吗


解决方案:

在AirSquid的帮助下,我找到了解决问题的简单方法。我放弃了使用pyomos分段函数,并为模型引入了额外的约束。以下模型可以根据需要工作

import pyomo.environ as po

costsX1 = 4
costsX2 = 6

costsY1 = 2
costsY2 = 1

a1 = 4
a2 = 3

model = po.ConcreteModel()

model.VarX1 = po.Var(bounds=(0,6))
model.VarX2 = po.Var(bounds=(0,5))

model.VarY1 = po.Var(within=po.Binary)
model.VarY2 = po.Var(within=po.Binary)

model.cons1 = po.Constraint(expr=model.VarX1+model.VarX2==5)
model.cons2 = po.Constraint(expr=a1*model.VarY1+ a2*model.VarY2>=3)

model.con3 = po.Constraint(expr=model.VarY1 <= model.VarX1)
model.con4 = po.Constraint(expr=model.VarY1 >= model.VarX1/6)

model.con5 = po.Constraint(expr=model.VarY2 <= model.VarX2)
model.con6 = po.Constraint(expr=model.VarY2 >= model.VarX2/5)

model.obj = po.Objective(expr=costsX1*model.VarX1+costsY1*a1*model.VarY1+costsX2*model.VarX2+costsY2*a2*model.VarY2,
                         sense=po.minimize)

opt = po.SolverFactory('cbc')
result_obj = opt.solve(model, tee=True)

model.pprint()

Tags: nonefalsea2modelvara1popts
1条回答
网友
1楼 · 发布于 2024-09-29 19:35:47

换个角度思考这个问题。考虑^ {CD1}}是一个“指示器”变量。在这种情况下,它表示x在哪个范围内,或者更准确地说,它表示x的上下限。所以,现在的任务是用二进制数做一点代数,使之工作

让我们考虑一下低

x >= 1 * y

适用于y in {0, 1}的两个值

和高。。。如果y=0,我们想要1,如果y=1,我们想要6。。。一点代数:

x <= 1 + 5 * y

相关问题 更多 >

    热门问题