首页 > 解决方案 > [Pyomo]如何通过循环生成约束

问题描述

全部

我想创建一组约束,如下所示:

Pg[0] <= Pmax[0]

Pg[1] <= Pmax[1]

Pg[3] <= Pmax[3]

Pg[4] <= Pmax[4]

Pg[5] <= Pmax[5]

而且,我的代码如下:

import pyomo.environ as pyo

model = pyo.ConcreteModel()
Ngen = 5
Pmax = [40, 170, 520, 200, 100]
model.Ngen = pyo.Set(dimen=Ngen)
model.Pg = pyo.Var(model.Ngen)

def Co1(model):
    return ((model.Pg[ii] for ii in model.Ngen) <= (Pmax[jj]  for jj in range(Ngen)))

model.Co1 = pyo.Constraint(rule=Co1)

但是,Python 控制台告诉我:

“ TypeError: 'generator' 和 'generator' 的实例之间不支持 '<=' ”

我该如何纠正?

另一个问题,如果 Pmax 不是一个列表,而是一个 numpy-ndarray。会有所不同吗?

多谢!

标签: pyomo

解决方案


线索在于您的约束是在一个集合上定义的。Pyomo 允许您传递argsConstraint定义该约束的集合的构造函数。

因此,您的最后一行应该类似于:

model.Co1 = pyo.Constraint(model.Ngen, rule=Co1)

第二个问题是约束表达式本身。既然这是针对 a 定义的Set,您只需要根据给定索引(例如 )来表达约束i,因为 therule还需要与每个 的每个索引有关的Set参数Constraint

def Co1(model, i):
    return model.Pg[i] <= Pmax[i]

最后,Set你定义的是 of size=5,不是dimen=5。集合通常是dimen=1,除非您正在使用网络的弧链接,在这种情况下,它们的维度为 2。由于您的集合是在整数上定义的,因此添加它的最简单方法是通过RangeSet它定义从 1 到 N 的所有整数:

model.Ngen = pyo.RangeSet(Ngen)

鉴于此,唯一需要更改的是列表Pmax是 0 索引的,因此我们的约束将需要考虑i偏移 1:

import pyomo.environ as pyo

model = pyo.ConcreteModel()
Ngen = 5
Pmax = [40, 170, 520, 200, 100]
model.Ngen = pyo.RangeSet(Ngen)
model.Pg = pyo.Var(model.Ngen)

def Co1(model, i):
    return model.Pg[i] <= Pmax[i - 1]

model.Co1 = pyo.Constraint(model.Ngen, rule = Co1)

model.pprint()

# 1 RangeSet Declarations
#     Ngen : Dim=0, Dimen=1, Size=5, Domain=Integers, Ordered=True, Bounds=(1, 5)
#         Virtual
# 
# 1 Var Declarations
#     Pg : Size=5, Index=Ngen
#         Key : Lower : Value : Upper : Fixed : Stale : Domain
#           1 :  None :  None :  None : False :  True :  Reals
#           2 :  None :  None :  None : False :  True :  Reals
#           3 :  None :  None :  None : False :  True :  Reals
#           4 :  None :  None :  None : False :  True :  Reals
#           5 :  None :  None :  None : False :  True :  Reals
# 
# 1 Constraint Declarations
#     Co1 : Size=5, Index=Ngen, Active=True
#         Key : Lower : Body  : Upper : Active
#           1 :  -Inf : Pg[1] :  40.0 :   True
#           2 :  -Inf : Pg[2] : 170.0 :   True
#           3 :  -Inf : Pg[3] : 520.0 :   True
#           4 :  -Inf : Pg[4] : 200.0 :   True
#           5 :  -Inf : Pg[5] : 100.0 :   True
# 
# 3 Declarations: Ngen Pg Co1

NumPy 数组可以以与列表完全相同的方式进行切片,因此如果您进行更改,上述约束仍然可以正常工作Pmax = np.array([40, 170, 520, 200, 100])


推荐阅读