我正在优化电池存储与太阳能光伏相结合的行为,以产生尽可能高的收入流。 我现在想再增加一种收入来源:调峰(或需求费用减少)
我的做法如下:
现在,有人看到如何制定这样的约束(P_GridMax)的解决方案吗?我已经更新了目标函数并定义了 P_Grid。 任何其他方法也将受到欢迎。
这是我的模型的相关部分,其中 P_xxx = 潮流向量,C_xxx = 价格向量,...
m.P_Grid = Var(m.i_TIME, within = NonNegativeReals)
m.P_GridMax = Var(m.i_TIME, within = NonNegativeReals)
# Minimize electricity bill
def Total_cost(m):
return ... + sum(m.P_GridMax[i] * m.C_PowerCosts[i] for i in m.i_TIME) - ...
m.Cost = Objective(rule=Total_cost)
## Peak Shaving constraints
def Grid_Def(m,i):
return m.P_Grid[i] = m.P_GridLoad[i] + m.P_GridBatt[i]
m.Bound_Grid = Constraint(m.i_TIME,rule=Grid_Def)
def Peak_Rule(m,i):
????
????
????
????
m.Bound_Peak = Constraint(m.i_TIME,rule=Peak_Rule)
提前非常感谢您!请注意,我对 python/pyomo 编码的经验很少,我非常感谢您提供广泛的解释:)
最好的, 马蒂亚斯
另一个想法是,您实际上不需要用时间来索引您的
P_GridMax
变量。
如果您正在处理需求成本,它们往往会在一段时间内固定下来,或者在您的情况下,它们似乎在整个问题范围内都是固定的(因为您只寻找一个最大值)。
在这种情况下,您只需要做:
m.P_GridMax = pyo.Var(domain=pyo.NonNegativeReals)
def Peak_Rule(m, i):
return m.P_GridMax >= m.P_Grid[i]
m.Bound_Peak = pyo.Constraint(m.i_TIME,rule=Peak_Rule)
如果您真的决定按元素相乘向量,您也可以创建一个表示索引乘积的新变量,并应用相同的原理来提取最大值。
这是一种方法:
引入一个二进制辅助变量
ismax[i] for i in i_TIME
。如果在周期 i
内获得最大值,则该变量为 1,否则为 0。那么显然你有一个约束sum(ismax[i] for i in i_TIME) == 1
:必须在一个周期内达到最大值。
现在您需要两个额外的约束:
ismax[i] == 0
那么P_GridMax[i] == 0
。ismax[i] == 1
,那么对于所有j in i_TIME
,我们必须拥有P_GridMax[i] >= P_GridMax[j]
。制定这一点的最佳方法是使用指标约束,但我不了解 Pyomo,所以我不知道它是否支持(我想它支持,但我不知道如何编写它们)。所以我会给出一个大 M 公式。
对于此公式,您需要定义一个常数
M
,以便 P_Grid[i]
对于任何 i
都不能超过该值。这样第一个约束就变成了
P_GridMax[i] <= M * ismax[i]
该约束迫使
P_GridMax[i]
为 0,除非 ismax[i] == 1
。对于 ismax[i] == 1
来说这是多余的。
第二个约束适用于所有 j in i_TIME
P_GridMax[i] + M * (1 - ismax[i]) >= P_Grid[j]
如果
ismax[i] == 0
那么这个约束的左边至少是 M
,所以根据 M
的定义,无论 P_GridMax[i]
的值是多少(第一个约束力 P_Grid[i] == 0
在这种情况下)。对于 ismax[i] == 1
,约束的左侧变为 P_GridMax[i]
,正是我们想要的。
如果您将 Pyomo 与 Ipopt 求解器一起使用,请尝试将二次罚函数直接合并到目标函数中 - 这对我有用