使用约束列表创建 Pyomo 的 ConstraintList 而不是单独添加它们?
Creating Pyomo's ConstraintList with a list of constraints rather than adding them individually?
我目前将我的 Pyomo 变量存储在 Pandas 数据框中,并一直在使用它来生成约束数组。
有没有一种方法可以将它们添加到我的模型中(例如,通过用它初始化一个 ConstraintList)而不是循环遍历它们并单独添加它们?我认为我无法使用规则来创建约束,因为我正在根据我的 Pandas 数据框进行索引。
这就是我存储变量的方式 - 我使用 Pandas 因为我发现在我的数据框中按值索引真的很容易:
model.duid_bids = pe.Var(bid_df['DUID_BAND_DATETIME'], domain=pe.PositiveReals)
bid_df['PE_BIDS'] = bid_df['DUID_BAND_DATETIME'].apply(lambda x: model.duid_bids[x])
我想做这样的事情,但行不通:
model.bid_volume = pe.Constraint(expr=bid_df['PE_BIDS'] <= bid_df['VOLUME'])
如果我像这样单独添加它们,它会起作用:
pe.Constraint(expr=bid_df['PE_BIDS'].iloc[0] <= bid_df['VOLUME'].iloc[0])
非常感谢。
我认为您太过努力将 pyomo
推入 pandas
框。 :).但这只是一个意见。我看不出这样做有什么好处,因为你没有在此处“矢量化”任何操作,因为 pyomo
约束构造没有矢量化。
我建议(其他人可能不同)只在 pyomo
中进行优化,而不将任何组件放入 df,而是根据约束的需要提取常量。关于我是否会将您正在使用的索引集放入 pyomo Set
,我认为这会使事情变得更容易 T/S,并且 pyomo
将制作一个虚拟集,尚无定论(s) 内部无论如何,您可以在下面的第一个示例中看到,但这是一个侧面故事。
这里有 2 个我认为可行的结构削减,并且与 pandas
有一些区别。这假设您在 df 中拥有的 datetime
是唯一的,并且可以为简单起见将其放入索引中。 (实际上它必须是唯一的,因为您已经将它用作索引集...回答了我自己的问题)
import pyomo.environ as pe
import pandas as pd
data = {'DATETIME': [1,2,3],
'VOLUME': [1000, 2000, 3000]}
df = pd.DataFrame(data)
df.set_index('DATETIME', inplace=True)
print(df.head()) # quick check...
model = pe.ConcreteModel()
model.duid_bids = pe.Var(df.index, domain=pe.PositiveReals)
# volume constraint
def vol_constraint(m, date):
return model.duid_bids[date] <= df['VOLUME'].loc[date]
model.vol_constraint = pe.Constraint(df.index, rule=vol_constraint)
model.pprint()
############ alternate approach: full pyomo... ?
model2 = pe.ConcreteModel()
# sets
model2.D = pe.Set(initialize=df.index)
# vars
model2.bid = pe.Var(model2.D, domain=pe.PositiveReals)
# constraint
def vol_constraint2(m, date):
return model2.bid[date] <= df['VOLUME'][date]
model2.vol_constraint = pe.Constraint(model2.D, rule=vol_constraint2)
model2.pprint()
model2.obj = pe.Objective(expr=sum(model2.bid[date] for date in model2.D), sense=pe.maximize)
solver = pe.SolverFactory('glpk')
status = solver.solve(model2)
print(status)
# stuff the result into the dataframe
df['bid'] = pd.Series(model2.bid.get_values())
print(df)
生成:
VOLUME
DATETIME
1 1000
2 2000
3 3000
2 Set Declarations
duid_bids_index : Size=1, Index=None, Ordered=False
Key : Dimen : Domain : Size : Members
None : 1 : Any : 3 : {1, 2, 3}
vol_constraint_index : Size=1, Index=None, Ordered=False
Key : Dimen : Domain : Size : Members
None : 1 : Any : 3 : {1, 2, 3}
1 Var Declarations
duid_bids : Size=3, Index=duid_bids_index
Key : Lower : Value : Upper : Fixed : Stale : Domain
1 : 0 : None : None : False : True : PositiveReals
2 : 0 : None : None : False : True : PositiveReals
3 : 0 : None : None : False : True : PositiveReals
1 Constraint Declarations
vol_constraint : Size=3, Index=vol_constraint_index, Active=True
Key : Lower : Body : Upper : Active
1 : -Inf : duid_bids[1] : 1000.0 : True
2 : -Inf : duid_bids[2] : 2000.0 : True
3 : -Inf : duid_bids[3] : 3000.0 : True
4 Declarations: duid_bids_index duid_bids vol_constraint_index vol_constraint
为清楚起见,将模型 2 分开...
1 Set Declarations
D : Size=1, Index=None, Ordered=Insertion
Key : Dimen : Domain : Size : Members
None : 1 : Any : 3 : {1, 2, 3}
1 Var Declarations
bid : Size=3, Index=D
Key : Lower : Value : Upper : Fixed : Stale : Domain
1 : 0 : None : None : False : True : PositiveReals
2 : 0 : None : None : False : True : PositiveReals
3 : 0 : None : None : False : True : PositiveReals
1 Constraint Declarations
vol_constraint : Size=3, Index=D, Active=True
Key : Lower : Body : Upper : Active
1 : -Inf : bid[1] : 1000.0 : True
2 : -Inf : bid[2] : 2000.0 : True
3 : -Inf : bid[3] : 3000.0 : True
3 Declarations: D bid vol_constraint
Problem:
- Name: unknown
Lower bound: 6000.0
Upper bound: 6000.0
Number of objectives: 1
Number of constraints: 4
Number of variables: 4
Number of nonzeros: 4
Sense: maximize
Solver:
- Status: ok
Termination condition: optimal
Statistics:
Branch and bound:
Number of bounded subproblems: 0
Number of created subproblems: 0
Error rc: 0
Time: 0.010575056076049805
Solution:
- number of solutions: 0
number of solutions displayed: 0
VOLUME bid
DATETIME
1 1000 1000.0
2 2000 2000.0
3 3000 3000.0
我目前将我的 Pyomo 变量存储在 Pandas 数据框中,并一直在使用它来生成约束数组。
有没有一种方法可以将它们添加到我的模型中(例如,通过用它初始化一个 ConstraintList)而不是循环遍历它们并单独添加它们?我认为我无法使用规则来创建约束,因为我正在根据我的 Pandas 数据框进行索引。
这就是我存储变量的方式 - 我使用 Pandas 因为我发现在我的数据框中按值索引真的很容易:
model.duid_bids = pe.Var(bid_df['DUID_BAND_DATETIME'], domain=pe.PositiveReals)
bid_df['PE_BIDS'] = bid_df['DUID_BAND_DATETIME'].apply(lambda x: model.duid_bids[x])
我想做这样的事情,但行不通:
model.bid_volume = pe.Constraint(expr=bid_df['PE_BIDS'] <= bid_df['VOLUME'])
如果我像这样单独添加它们,它会起作用:
pe.Constraint(expr=bid_df['PE_BIDS'].iloc[0] <= bid_df['VOLUME'].iloc[0])
非常感谢。
我认为您太过努力将 pyomo
推入 pandas
框。 :).但这只是一个意见。我看不出这样做有什么好处,因为你没有在此处“矢量化”任何操作,因为 pyomo
约束构造没有矢量化。
我建议(其他人可能不同)只在 pyomo
中进行优化,而不将任何组件放入 df,而是根据约束的需要提取常量。关于我是否会将您正在使用的索引集放入 pyomo Set
,我认为这会使事情变得更容易 T/S,并且 pyomo
将制作一个虚拟集,尚无定论(s) 内部无论如何,您可以在下面的第一个示例中看到,但这是一个侧面故事。
这里有 2 个我认为可行的结构削减,并且与 pandas
有一些区别。这假设您在 df 中拥有的 datetime
是唯一的,并且可以为简单起见将其放入索引中。 (实际上它必须是唯一的,因为您已经将它用作索引集...回答了我自己的问题)
import pyomo.environ as pe
import pandas as pd
data = {'DATETIME': [1,2,3],
'VOLUME': [1000, 2000, 3000]}
df = pd.DataFrame(data)
df.set_index('DATETIME', inplace=True)
print(df.head()) # quick check...
model = pe.ConcreteModel()
model.duid_bids = pe.Var(df.index, domain=pe.PositiveReals)
# volume constraint
def vol_constraint(m, date):
return model.duid_bids[date] <= df['VOLUME'].loc[date]
model.vol_constraint = pe.Constraint(df.index, rule=vol_constraint)
model.pprint()
############ alternate approach: full pyomo... ?
model2 = pe.ConcreteModel()
# sets
model2.D = pe.Set(initialize=df.index)
# vars
model2.bid = pe.Var(model2.D, domain=pe.PositiveReals)
# constraint
def vol_constraint2(m, date):
return model2.bid[date] <= df['VOLUME'][date]
model2.vol_constraint = pe.Constraint(model2.D, rule=vol_constraint2)
model2.pprint()
model2.obj = pe.Objective(expr=sum(model2.bid[date] for date in model2.D), sense=pe.maximize)
solver = pe.SolverFactory('glpk')
status = solver.solve(model2)
print(status)
# stuff the result into the dataframe
df['bid'] = pd.Series(model2.bid.get_values())
print(df)
生成:
VOLUME
DATETIME
1 1000
2 2000
3 3000
2 Set Declarations
duid_bids_index : Size=1, Index=None, Ordered=False
Key : Dimen : Domain : Size : Members
None : 1 : Any : 3 : {1, 2, 3}
vol_constraint_index : Size=1, Index=None, Ordered=False
Key : Dimen : Domain : Size : Members
None : 1 : Any : 3 : {1, 2, 3}
1 Var Declarations
duid_bids : Size=3, Index=duid_bids_index
Key : Lower : Value : Upper : Fixed : Stale : Domain
1 : 0 : None : None : False : True : PositiveReals
2 : 0 : None : None : False : True : PositiveReals
3 : 0 : None : None : False : True : PositiveReals
1 Constraint Declarations
vol_constraint : Size=3, Index=vol_constraint_index, Active=True
Key : Lower : Body : Upper : Active
1 : -Inf : duid_bids[1] : 1000.0 : True
2 : -Inf : duid_bids[2] : 2000.0 : True
3 : -Inf : duid_bids[3] : 3000.0 : True
4 Declarations: duid_bids_index duid_bids vol_constraint_index vol_constraint
为清楚起见,将模型 2 分开...
1 Set Declarations
D : Size=1, Index=None, Ordered=Insertion
Key : Dimen : Domain : Size : Members
None : 1 : Any : 3 : {1, 2, 3}
1 Var Declarations
bid : Size=3, Index=D
Key : Lower : Value : Upper : Fixed : Stale : Domain
1 : 0 : None : None : False : True : PositiveReals
2 : 0 : None : None : False : True : PositiveReals
3 : 0 : None : None : False : True : PositiveReals
1 Constraint Declarations
vol_constraint : Size=3, Index=D, Active=True
Key : Lower : Body : Upper : Active
1 : -Inf : bid[1] : 1000.0 : True
2 : -Inf : bid[2] : 2000.0 : True
3 : -Inf : bid[3] : 3000.0 : True
3 Declarations: D bid vol_constraint
Problem:
- Name: unknown
Lower bound: 6000.0
Upper bound: 6000.0
Number of objectives: 1
Number of constraints: 4
Number of variables: 4
Number of nonzeros: 4
Sense: maximize
Solver:
- Status: ok
Termination condition: optimal
Statistics:
Branch and bound:
Number of bounded subproblems: 0
Number of created subproblems: 0
Error rc: 0
Time: 0.010575056076049805
Solution:
- number of solutions: 0
number of solutions displayed: 0
VOLUME bid
DATETIME
1 1000 1000.0
2 2000 2000.0
3 3000 3000.0