线索在于您的约束是在一个集合上定义的。 Pyomo 允许您将 args 传递给定义该约束的集合的 Constraint 构造函数。
因此,您的最后一行应该类似于:
model.Co1 = pyo.Constraint(model.Ngen, rule=Co1)
第二个问题是约束表达式本身。现在这是针对Set 定义的,您只需根据给定索引(例如i)表达约束,因为rule 还需要与每个Set 的每个索引有关的参数Constraint:
def Co1(model, i):
return model.Pg[i] <= Pmax[i]
最后,您定义的Set 属于size=5,而不是dimen=5。集合通常是dimen=1,除非您正在使用网络的弧链接,在这种情况下,它们的维度为 2。由于您的集合是在整数上定义的,因此添加它的最简单方法是通过 RangeSet 定义所有从 1 到 N 的整数:
model.Ngen = pyo.RangeSet(Ngen)
鉴于此,唯一需要更改的是列表 Pmax 是 0 索引的,因此我们的约束需要考虑 i 被偏移一:
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]),上述约束仍然可以正常工作