Pyomo 约束问题:不返回约束结果

Pyomo constraint issue: not returning constrained result

我在 pyomo 中设置了一个不约束求解器的约束。

约束如下:

def revenue_positive(model,t):
        for t in model.T:
            return (model.D[t] * model.P[t]) >= 0
    
    model.positive_revenue = Constraint(model.T, rule=revenue_positive)

模型参数为:

model = ConcreteModel()
model.T = Set(doc='quarter of year', initialize=df.index.tolist(), ordered=True)
model.P = Param(model.T, initialize=df['price'].to_dict(), within=Any, doc='Price for each quarter')

model.C = Var(model.T, domain=NonNegativeReals)
model.D = Var(model.T, domain=NonNegativeReals)

income = sum(df.loc[t, 'price'] * model.D[t] for t in model.T)
expenses = sum(df.loc[t, 'price'] * model.C[t] for t in model.T)
profit = income - expenses
model.objective = Objective(expr=profit, sense=maximize)
    
# Solve the model
solver = SolverFactory('cbc')
solver.solve(model)

df 数据帧是:

df                   time_stamp  price Status  imbalance  Difference Situation  ... week month  hour_of_day  day_of_week  day_of_year  yearly_quarter
quarter                                                                     ...                                                                  
0       2021-01-01 00:00:00  64.84  Final         16          -3   Deficit  ...   00     1            0            4            1               1
1       2021-01-01 00:15:00  13.96  Final         38           2   Surplus  ...   00     1            0            4            1               1
2       2021-01-01 00:30:00  12.40  Final         46           1   Surplus  ...   00     1            0            4            1               1
3       2021-01-01 00:45:00   7.70  Final         65          14   Surplus  ...   00     1            0            4            1               1
4       2021-01-01 01:00:00  64.25  Final          3          -9   Deficit  ...   00     1            1            4            1               1

objective是为了约束求解器不接受负收益。因此它不起作用,因为求解器传递了 6 个负收入值。查看收益为负的指数,系统似乎选择以负价格卖出,然后以“更”负的价格买入,因此从优化的角度来看,这是可以的。如果我们禁止求解器这样做,我想检查结果的差异。欢迎任何输入,在网上搜索了很多次,仍然不是正确的写法。

我对返回的约束做了 pprint():

positive_revenue : Size=35040, Index=T, Active=True

更新以下新约束代码:

def revenue_positive(model,t):
        return model.D[t] * model.P[t] >= 0
        
model.positive_revenue = Constraint(model.T, rule=revenue_positive)

Return出现以下错误:

ERROR: Rule failed when generating expression for constraint positive_revenue
    with index 283: ValueError: Invalid constraint expression. The constraint
    expression resolved to a trivial Boolean (True) instead of a Pyomo object.
    Please modify your rule to return Constraint.Feasible instead of True.

    Error thrown for Constraint 'positive_revenue[283]'
ERROR: Constructing component 'positive_revenue' from data=None failed:
    ValueError: Invalid constraint expression. The constraint expression
    resolved to a trivial Boolean (True) instead of a Pyomo object. Please
    modify your rule to return Constraint.Feasible instead of True.

    Error thrown for Constraint 'positive_revenue[283]'
Traceback (most recent call last):
  File "/home/olivier/Desktop/Elia - BESS/run_imbalance.py", line 25, in <module>
    results_df = optimize_year(df)
  File "/home/olivier/Desktop/Elia - BESS/battery_model_imbalance.py", line 122, in optimize_year
    model.positive_revenue = Constraint(model.T, rule=revenue_positive)
  File "/home/olivier/anaconda3/lib/python3.9/site-packages/pyomo/core/base/block.py", line 542, in __setattr__
    self.add_component(name, val)
  File "/home/olivier/anaconda3/lib/python3.9/site-packages/pyomo/core/base/block.py", line 1087, in add_component
    val.construct(data)
  File "/home/olivier/anaconda3/lib/python3.9/site-packages/pyomo/core/base/constraint.py", line 781, in construct
    self._setitem_when_not_present(
  File "/home/olivier/anaconda3/lib/python3.9/site-packages/pyomo/core/base/indexed_component.py", line 778, in _setitem_when_not_present
    obj.set_value(value)
  File "/home/olivier/anaconda3/lib/python3.9/site-packages/pyomo/core/base/constraint.py", line 506, in set_value
    raise ValueError(
ValueError: Invalid constraint expression. The constraint expression resolved to a trivial Boolean (True) instead of a Pyomo object. Please modify your rule to return Constraint.Feasible instead of True.

Error thrown for Constraint 'positive_revenue[283]'

所以有 2 个问题与您的限制有关。不清楚是否是剪切和粘贴问题。

  1. return 语句之后,使约束的函数调用似乎缩进并位于函数内部,使其成为无法访问的代码。可能只是 post.

    中的间距
  2. 您在函数中错误地添加了一个循环。您将参数 t 作为函数参数传递,然后用 for 循环将其吹走,该循环仅对 Tt 的第一个值执行,然后点击 return声明。删除循环。当您在 pyomo 中使用 rule= 结构时,它将为您在 Constraint(xx, rule=) 结构中使用的集合的每个实例调用规则。

所以我认为你应该:

def revenue_positive(model, t):
  return model.D[t] * model.P[t] >= 0
    
model.positive_revenue = Constraint(model.T, rule=revenue_positive)

已更新回复:您添加的错误。

错误引用了第283个索引。我敢打赌 price[283] 是零,所以你乘以一个零并杀死你的变量。

您可以在函数中添加检查以检查价格是否为零,在这种情况下,只需 return pyo.Constraint.Feasible,这是不重要的 return不影响模型(或崩溃)