使用约束列表创建 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