pyomo:如何仅在集合的一部分中索引变量?
pyomo: how to index Variable in only part of a Set?
我正在尝试在 pyomo
优化模型中跟踪 SOC。我有很多 BEV,我想跟踪每个 SOC。我传递给 pe.Objective
的 xpression 如下所示:
sum(sum(model.SOC[t+1, b] - model.SOC[t, b] for b in model.buses) for t in model.times)
model.buses
和 model.times
是我声明为 pe.Set
的两个集合。时间从 (0, ...., 95) 开始。因此,在 model.times
的最后一次迭代中,它尝试访问 model.SOC[96, b]
导致 KeyError
.
的内容
有没有办法告诉 pyomo 找出集合的最后一个元素来防止这个错误?
类似于:
sum(sum(model.SOC[t+1, b] - model.SOC[t, b] for b in model.buses) for t in model.times[0:-2])
不幸的是,这也引发了一个错误:
IndexError: times indices must be integers, not slice
这是一个应该重现错误的最小示例:
import pyomo.environ as pe
solver = pe.SolverFactory('glpk')
model = pe.ConcreteModel('Test')
model.times = pe.Set(initialize=list(range(96)))
model.buses = pe.Set(initialize=list(range(5)))
model.SOC = pe.Var(model.times*model.buses, domain=pe.PositiveReals)
def example_rule(model):
return sum(sum(model.SOC[t+1, b] - model.SOC[t, b] for b in model.buses) for t in model.times)
model.obj = pe.Objective(rule=example_rule, sense=pe.maximize)
model.pprint()
非常感谢!
是的,有几种方法可以做到这一点。首先,如果要索引的集合是有序的(这是默认设置),则可以通过各种方式对集合使用 first
、last
和 prev
方法。 (请参阅下面我对您的代码所做的修改)
其次,您始终可以构建自己的子集并将其放入或不放入模型中。下面的第二个模型显示了任意复杂子集的构造并将其放入模型中。该集合可用作 objective 或约束的基础。
此解决方案与此类似
import pyomo.environ as pe
solver = pe.SolverFactory('glpk')
model = pe.ConcreteModel('Test')
model.times = pe.Set(initialize=list(range(5)), ordered=True) # ordered is default, this is for clarity...
model.buses = pe.Set(initialize=list(range(2)))
model.SOC = pe.Var(model.times*model.buses, domain=pe.PositiveReals)
def example_rule(model):
return sum(sum(model.SOC[t+1, b] - model.SOC[t, b] for b in model.buses) for t in model.times if t != model.times.last())
model.obj = pe.Objective(rule=example_rule, sense=pe.maximize)
model.pprint()
# making your own subset...
times = 10
model2 = pe.ConcreteModel("other")
model2.times = pe.Set(initialize=range(times))
# make a subset of the even values that are no more than 4 values close to the end....
model2.times_subset = pe.Set(initialize=[t for t in model2.times if t%2==0 and t <= times-4])
model2.pprint()
产量:
3 Set Declarations
SOC_index : Size=1, Index=None, Ordered=True
Key : Dimen : Domain : Size : Members
None : 2 : times*buses : 10 : {(0, 0), (0, 1), (1, 0), (1, 1), (2, 0), (2, 1), (3, 0), (3, 1), (4, 0), (4, 1)}
buses : Size=1, Index=None, Ordered=Insertion
Key : Dimen : Domain : Size : Members
None : 1 : Any : 2 : {0, 1}
times : Size=1, Index=None, Ordered=Insertion
Key : Dimen : Domain : Size : Members
None : 1 : Any : 5 : {0, 1, 2, 3, 4}
1 Var Declarations
SOC : Size=10, Index=SOC_index
Key : Lower : Value : Upper : Fixed : Stale : Domain
(0, 0) : 0 : None : None : False : True : PositiveReals
(0, 1) : 0 : None : None : False : True : PositiveReals
(1, 0) : 0 : None : None : False : True : PositiveReals
(1, 1) : 0 : None : None : False : True : PositiveReals
(2, 0) : 0 : None : None : False : True : PositiveReals
(2, 1) : 0 : None : None : False : True : PositiveReals
(3, 0) : 0 : None : None : False : True : PositiveReals
(3, 1) : 0 : None : None : False : True : PositiveReals
(4, 0) : 0 : None : None : False : True : PositiveReals
(4, 1) : 0 : None : None : False : True : PositiveReals
1 Objective Declarations
obj : Size=1, Index=None, Active=True
Key : Active : Sense : Expression
None : True : maximize : SOC[1,0] - SOC[0,0] + SOC[1,1] - SOC[0,1] + SOC[2,0] - SOC[1,0] + SOC[2,1] - SOC[1,1] + SOC[3,0] - SOC[2,0] + SOC[3,1] - SOC[2,1] + SOC[4,0] - SOC[3,0] + SOC[4,1] - SOC[3,1]
5 Declarations: times buses SOC_index SOC obj
2 Set Declarations
times : Size=1, Index=None, Ordered=Insertion
Key : Dimen : Domain : Size : Members
None : 1 : Any : 10 : {0, 1, 2, 3, 4, 5, 6, 7, 8, 9}
times_subset : Size=1, Index=None, Ordered=Insertion
Key : Dimen : Domain : Size : Members
None : 1 : Any : 4 : {0, 2, 4, 6}
2 Declarations: times times_subset
[Finished in 553ms]
我正在尝试在 pyomo
优化模型中跟踪 SOC。我有很多 BEV,我想跟踪每个 SOC。我传递给 pe.Objective
的 xpression 如下所示:
sum(sum(model.SOC[t+1, b] - model.SOC[t, b] for b in model.buses) for t in model.times)
model.buses
和 model.times
是我声明为 pe.Set
的两个集合。时间从 (0, ...., 95) 开始。因此,在 model.times
的最后一次迭代中,它尝试访问 model.SOC[96, b]
导致 KeyError
.
有没有办法告诉 pyomo 找出集合的最后一个元素来防止这个错误?
类似于:
sum(sum(model.SOC[t+1, b] - model.SOC[t, b] for b in model.buses) for t in model.times[0:-2])
不幸的是,这也引发了一个错误:
IndexError: times indices must be integers, not slice
这是一个应该重现错误的最小示例:
import pyomo.environ as pe
solver = pe.SolverFactory('glpk')
model = pe.ConcreteModel('Test')
model.times = pe.Set(initialize=list(range(96)))
model.buses = pe.Set(initialize=list(range(5)))
model.SOC = pe.Var(model.times*model.buses, domain=pe.PositiveReals)
def example_rule(model):
return sum(sum(model.SOC[t+1, b] - model.SOC[t, b] for b in model.buses) for t in model.times)
model.obj = pe.Objective(rule=example_rule, sense=pe.maximize)
model.pprint()
非常感谢!
是的,有几种方法可以做到这一点。首先,如果要索引的集合是有序的(这是默认设置),则可以通过各种方式对集合使用 first
、last
和 prev
方法。 (请参阅下面我对您的代码所做的修改)
其次,您始终可以构建自己的子集并将其放入或不放入模型中。下面的第二个模型显示了任意复杂子集的构造并将其放入模型中。该集合可用作 objective 或约束的基础。
此解决方案与此类似
import pyomo.environ as pe
solver = pe.SolverFactory('glpk')
model = pe.ConcreteModel('Test')
model.times = pe.Set(initialize=list(range(5)), ordered=True) # ordered is default, this is for clarity...
model.buses = pe.Set(initialize=list(range(2)))
model.SOC = pe.Var(model.times*model.buses, domain=pe.PositiveReals)
def example_rule(model):
return sum(sum(model.SOC[t+1, b] - model.SOC[t, b] for b in model.buses) for t in model.times if t != model.times.last())
model.obj = pe.Objective(rule=example_rule, sense=pe.maximize)
model.pprint()
# making your own subset...
times = 10
model2 = pe.ConcreteModel("other")
model2.times = pe.Set(initialize=range(times))
# make a subset of the even values that are no more than 4 values close to the end....
model2.times_subset = pe.Set(initialize=[t for t in model2.times if t%2==0 and t <= times-4])
model2.pprint()
产量:
3 Set Declarations
SOC_index : Size=1, Index=None, Ordered=True
Key : Dimen : Domain : Size : Members
None : 2 : times*buses : 10 : {(0, 0), (0, 1), (1, 0), (1, 1), (2, 0), (2, 1), (3, 0), (3, 1), (4, 0), (4, 1)}
buses : Size=1, Index=None, Ordered=Insertion
Key : Dimen : Domain : Size : Members
None : 1 : Any : 2 : {0, 1}
times : Size=1, Index=None, Ordered=Insertion
Key : Dimen : Domain : Size : Members
None : 1 : Any : 5 : {0, 1, 2, 3, 4}
1 Var Declarations
SOC : Size=10, Index=SOC_index
Key : Lower : Value : Upper : Fixed : Stale : Domain
(0, 0) : 0 : None : None : False : True : PositiveReals
(0, 1) : 0 : None : None : False : True : PositiveReals
(1, 0) : 0 : None : None : False : True : PositiveReals
(1, 1) : 0 : None : None : False : True : PositiveReals
(2, 0) : 0 : None : None : False : True : PositiveReals
(2, 1) : 0 : None : None : False : True : PositiveReals
(3, 0) : 0 : None : None : False : True : PositiveReals
(3, 1) : 0 : None : None : False : True : PositiveReals
(4, 0) : 0 : None : None : False : True : PositiveReals
(4, 1) : 0 : None : None : False : True : PositiveReals
1 Objective Declarations
obj : Size=1, Index=None, Active=True
Key : Active : Sense : Expression
None : True : maximize : SOC[1,0] - SOC[0,0] + SOC[1,1] - SOC[0,1] + SOC[2,0] - SOC[1,0] + SOC[2,1] - SOC[1,1] + SOC[3,0] - SOC[2,0] + SOC[3,1] - SOC[2,1] + SOC[4,0] - SOC[3,0] + SOC[4,1] - SOC[3,1]
5 Declarations: times buses SOC_index SOC obj
2 Set Declarations
times : Size=1, Index=None, Ordered=Insertion
Key : Dimen : Domain : Size : Members
None : 1 : Any : 10 : {0, 1, 2, 3, 4, 5, 6, 7, 8, 9}
times_subset : Size=1, Index=None, Ordered=Insertion
Key : Dimen : Domain : Size : Members
None : 1 : Any : 4 : {0, 2, 4, 6}
2 Declarations: times times_subset
[Finished in 553ms]