具有一个变量的多个索引的 pyomo 约束是否可能?
is pyomo constraint with multiple indexes of one variable possible?
有没有一种方法可以在一个约束内将多个索引设置为一个设定值,而不必为每个索引时间键入相同的变量。我提供了一个示例,假设您想优化电动汽车的充电时间,但不希望它在一天中的特定时间充电。下面的示例可以避免在第 4 小时和第 5 小时充电。但是,如果我想让它在一天中的 15 小时内不充电,但又不想写 m.EVcharge[0]+m.EVcharge[1]+... 怎么办? [:15] == 0 将不起作用,因为约束不能很好地处理 pyomo 中的切片。
def time_rule(m):
return m.EVcharge[4]+m.EVcharge[5] == 0
m.time_rule = Constraint(time, rule=time_rule)
是的。有多种方法可以做到这一点。您可以制作 m.time
和 的子集,仅 将该子集传递给约束规则,这会将它们约束为零,或者对子集求和并将其约束为零(两者都假设负充电是不可能的。)
或者,您可以更干净地使用数据或参数来保持任意时间块的限制并使用它,这使数据与模型分开,这通常是个好主意...
import pyomo.environ as pyo
# some background data on limits...
use_limit = { 0:3, # limited juice avial
1:3,
2:0, # no juice avail. :)
3:0}
m = pyo.ConcreteModel('EV Charge')
m.T = pyo.Set(initialize=range(6))
m.EV_charge = pyo.Var(m.T, domain=pyo.NonNegativeReals)
# Constraints
def charge_limit(m, time):
return m.EV_charge[time] <= use_limit[time]
m.C1 = pyo.Constraint(use_limit.keys(), rule=charge_limit)
m.pprint()
产量:
2 Set Declarations
C1_index : Size=1, Index=None, Ordered=False
Key : Dimen : Domain : Size : Members
None : 1 : Any : 4 : {0, 1, 2, 3}
T : Size=1, Index=None, Ordered=Insertion
Key : Dimen : Domain : Size : Members
None : 1 : Any : 6 : {0, 1, 2, 3, 4, 5}
1 Var Declarations
EV_charge : Size=6, Index=T
Key : Lower : Value : Upper : Fixed : Stale : Domain
0 : 0 : None : None : False : True : NonNegativeReals
1 : 0 : None : None : False : True : NonNegativeReals
2 : 0 : None : None : False : True : NonNegativeReals
3 : 0 : None : None : False : True : NonNegativeReals
4 : 0 : None : None : False : True : NonNegativeReals
5 : 0 : None : None : False : True : NonNegativeReals
1 Constraint Declarations
C1 : Size=4, Index=C1_index, Active=True
Key : Lower : Body : Upper : Active
0 : -Inf : EV_charge[0] : 3.0 : True
1 : -Inf : EV_charge[1] : 3.0 : True
2 : -Inf : EV_charge[2] : 0.0 : True
3 : -Inf : EV_charge[3] : 0.0 : True
有没有一种方法可以在一个约束内将多个索引设置为一个设定值,而不必为每个索引时间键入相同的变量。我提供了一个示例,假设您想优化电动汽车的充电时间,但不希望它在一天中的特定时间充电。下面的示例可以避免在第 4 小时和第 5 小时充电。但是,如果我想让它在一天中的 15 小时内不充电,但又不想写 m.EVcharge[0]+m.EVcharge[1]+... 怎么办? [:15] == 0 将不起作用,因为约束不能很好地处理 pyomo 中的切片。
def time_rule(m):
return m.EVcharge[4]+m.EVcharge[5] == 0
m.time_rule = Constraint(time, rule=time_rule)
是的。有多种方法可以做到这一点。您可以制作 m.time
和 的子集,仅 将该子集传递给约束规则,这会将它们约束为零,或者对子集求和并将其约束为零(两者都假设负充电是不可能的。)
或者,您可以更干净地使用数据或参数来保持任意时间块的限制并使用它,这使数据与模型分开,这通常是个好主意...
import pyomo.environ as pyo
# some background data on limits...
use_limit = { 0:3, # limited juice avial
1:3,
2:0, # no juice avail. :)
3:0}
m = pyo.ConcreteModel('EV Charge')
m.T = pyo.Set(initialize=range(6))
m.EV_charge = pyo.Var(m.T, domain=pyo.NonNegativeReals)
# Constraints
def charge_limit(m, time):
return m.EV_charge[time] <= use_limit[time]
m.C1 = pyo.Constraint(use_limit.keys(), rule=charge_limit)
m.pprint()
产量:
2 Set Declarations
C1_index : Size=1, Index=None, Ordered=False
Key : Dimen : Domain : Size : Members
None : 1 : Any : 4 : {0, 1, 2, 3}
T : Size=1, Index=None, Ordered=Insertion
Key : Dimen : Domain : Size : Members
None : 1 : Any : 6 : {0, 1, 2, 3, 4, 5}
1 Var Declarations
EV_charge : Size=6, Index=T
Key : Lower : Value : Upper : Fixed : Stale : Domain
0 : 0 : None : None : False : True : NonNegativeReals
1 : 0 : None : None : False : True : NonNegativeReals
2 : 0 : None : None : False : True : NonNegativeReals
3 : 0 : None : None : False : True : NonNegativeReals
4 : 0 : None : None : False : True : NonNegativeReals
5 : 0 : None : None : False : True : NonNegativeReals
1 Constraint Declarations
C1 : Size=4, Index=C1_index, Active=True
Key : Lower : Body : Upper : Active
0 : -Inf : EV_charge[0] : 3.0 : True
1 : -Inf : EV_charge[1] : 3.0 : True
2 : -Inf : EV_charge[2] : 0.0 : True
3 : -Inf : EV_charge[3] : 0.0 : True