用Gurobi求解Pyomo中的squaredoot约束

2024-09-30 20:19:59 发布

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

我使用的是古罗比9.1.2和俾莫6.1.2

我在pyomo建模层中创建了一个MILP模型

为了推进我的研究,我需要对我的模型实现一个新的约束。这个新的约束有一个平方根,我想用古洛比来解决它

import pyomo.environ as pyo
...
model = pyo.AbstractModel()
#Set
model.J = pyo.Set(doc='Generation set')
model.t = pyo.Set(doc='datetime Set')
model.S = pyo.Set(doc='Storage Systems Set')
#Params
model.Delt = pyo.Param(model.t)
model.Us = pyo.Param()
model.Ud = pyo.Param()
model.Ss = pyo.Param()
model.Sd = pyo.Param()
model.erf = pyo.Param()
#Variables
model.pnomj = pyo.Var(model.J, domain=pyo.NonNegativeReals)
model.pjtResUp = pyo.Var(model.J, model.T, domain=pyo.NonNegativeReals)
model.pbesstResUp = pyo.Var(model.S, model.T, domain=pyo.NonNegativeReals)

我想要实现的约束就是这个 Quadratic Constraint

其中Δp^{SR+}{j,t}是model.pjtResUp,Δp^{SR+}{B,t}是model.pbesstResUp

def upReserves(model, t):
    return model.Us*model.pnomj['PV'] - model.Ud*model.Delt[t] + \
           model.erf*pyo.sqrt((model.Ss*model.pnomj['PV'])**2 + (model.Sd*model.Delt[t])**2) <= \
           sum(model.pjtResUp[j,t] for j in model.J) + model.pbesstResUp['BESS',t]

这给了我下一个值错误:

ValueError: Cannot write legal LP file.  Constraint 'upReserves[2020-01-01 00:00:00]' has a body with nonlinear terms.

This Answer中,他们说使用CPLEX创建LP文件时存在Pyomo问题,因为Gurobi甚至可以解决非凸问题(将参数options={'NonConvex':2}传递给SolverFactory)

有什么建议我可以查一下吗?提前感谢


Tags: 模型docmodelparamvardomainpyomous
1条回答
网友
1楼 · 发布于 2024-09-30 20:19:59

我要解决这个问题

为了避免圆锥约束样式约束中的非凸性,我这样做:

  1. 为了避免SOC约束中的非凸性,我使用了一个新的var(我们称之为g),这样:

     model.g = pyo.Var(model.T, doc='non-squared part of conic constraint')
    
  2. 添加圆锥约束的非平方根部分的新约束:

     def RHS_constraint(model, t):
      return model.g[t] == sum(model.pjtResUp[j,t] for j in model.J) + model.pbesstResUp['BESS',t] + (model.Ud*model.Delt[t] - model.Us*model.pnomj['PV'])
    

    model.RHS_约束=pyo.constraint(model.T,rule=RHS_约束)

  3. 为了避免创建Pyomo LP文件时出现非线性项中的ValueError,我对两边进行了平方:

     def upReserves(model, t):
         return model.g[t]**2 >= (model.erf**2)*((model.Ss*model.pnomj['PV'])**2 + (model.Sd*model.Delt[t])**2)
     model.upReserves= pyo.Constraint(model.T, rule=upReserves)
    

感谢那些至少看过这篇文章的人。如果你认为这种方法是错误的,我也在寻找新的方法

相关问题 更多 >