Pyomo:最小化向量中的最大值

问题描述 投票:0回答:3

我正在优化电池存储与太阳能光伏相结合的行为,以产生尽可能高的收入流。 我现在想再增加一种收入来源:调峰(或需求费用减少)

我的做法如下:

  • 除了每千瓦时的价格之外,工业客户还需要为其在一个时期内(i=1:end)从电网获取的最大电量(kW)付费,即所谓的需求费用
  • 这个最大量可以在向量 P_Grid = P_GridLoad(电网自消耗的能量)+ P_GridBatt(用于给电池充电的能量)中找到
  • 存在一个价格向量,它告诉所有时间点的每千瓦价格
  • 我现在想要生成一个向量 P_GridMax,该向量对于所有时间点都为零,但 P_Grid 最大值出现的那一刻(则它等于 max(P_Grid)。
  • 因此,向量 P_GridMax 由零和一个非零元素(不多!)组成
  • 这样做,我现在可以将此向量与价格向量相乘,对所有时间点求和并收到计费的需求费用
  • 通过将此向量包含到我的模型的目标中,我可以最大限度地减少这些费用

现在,有人看到如何制定这样的约束(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 编码的经验很少,我非常感谢您提供广泛的解释:)

最好的, 马蒂亚斯

python cplex battery pyomo mixed-integer-programming
3个回答
3
投票

另一个想法是,您实际上不需要用时间来索引您的

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)

如果您真的决定按元素相乘向量,您也可以创建一个表示索引乘积的新变量,并应用相同的原理来提取最大值。


1
投票

这是一种方法:

引入一个二进制辅助变量

ismax[i] for i in i_TIME
。如果在周期
i
内获得最大值,则该变量为 1,否则为 0。那么显然你有一个约束
sum(ismax[i] for i in i_TIME) == 1
:必须在一个周期内达到最大值。

现在您需要两个额外的约束:

  1. 如果
    ismax[i] == 0
    那么
    P_GridMax[i] == 0
  2. 如果
    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]
,正是我们想要的。


0
投票

如果您将 Pyomo 与 Ipopt 求解器一起使用,请尝试将二次罚函数直接合并到目标函数中 - 这对我有用

© www.soinside.com 2019 - 2024. All rights reserved.