【问题标题】:Linearization of quadratic constraint二次约束的线性化
【发布时间】:2021-11-21 06:23:57
【问题描述】:

我在我的 pyomo 模型中遇到了二次约束。它或多或少地用 gurobi 解决了它,但它经常给我带来记忆问题。所以我线性化了这个二次约束。但是,现在我遇到了另一个问题:Link to Stackoverflow。所以我想知道我是否在线性化中犯了错误。

问题在于热泵可以提供制冷或制热,但不能同时提供两者。 二次版:

h(t) = p(t)*bh(t)*COPh  #quadratic const
c(t) = p(t)*bc(t)*COPc  #quadratic const
h(t) <= cap_hp
c(t) <= cap_hp*(COPc/(COPc+1)
bh(t) + bc(t) <= 1

线性化版本:

p(t) = h(t)/COPh + c(t)/COPc
h(t) <= cap_hp
c(t) <= cap_hp*(COPc/(COPc+1)
h(t) <= M * b(t) + 0 * (1-b(t))
c(t) <= 0 * b(t) + M * (1-b(t))

决策变量:p(t):加热或冷却的电力消耗; h(t):加热输出; c(t):冷却输出; cap_hp:最大制热能力(热泵大小); b(t):二元变量,加热时为 1,冷却时为 0。或者在二次版本 bh(t) 或 bc(t) 中分别用于加热和冷却的二进制变量。 输入参数:COPh/c:“热泵在加热或冷却模式下的效率;M:大数

在 pyomo 代码下方(忽略热泵的技术细节,例如 COP,现在已更改)。 二次方:

m.b_hph = Var(year_i, ts_i, within=Binary)
m.b_hpc = Var(year_i, ts_i, within=Binary)
   
def ashpHeat_rule(m,y,ts):
    return sum(m.heat["heat_pump_air", hCons, y, ts] for hCons in hIn) == \
        sum(m.power[elSup, "heat_pump_air",y, ts] for elSup in elOut)\
        * m.b_hph[y,ts] * 3
m.const_ashpHeat = Constraint(year_i, ts_i, rule = ashpHeat_rule)

def ashpCool_rule(m,y,ts):
    return sum(m.cool["heat_pump_air", cCons, y, ts] for cCons in cIn) == \
        sum(m.power[elSup, "heat_pump_air",y, ts] for elSup in elOut)\
        * m.b_hpc[y,ts] * 2
m.const_ashpCool = Constraint(year_i, ts_i, rule = ashpCool_rule)

def ashpCapah_rule(m,y, ts):
    return sum(m.heat["heat_pump_air", hCons, y, ts] for hCons in hIn) <=\
        m.c_c["heat_pump_air"]
m.const_ashphCapa = Constraint(year_i, ts_i, rule = ashpCapah_rule)

def ashpCapac_rule(m,y, ts):
    return sum(m.cool["heat_pump_air", cCons, y, ts] for cCons in cIn) <=\
        m.c_c["heat_pump_air"] * (2/3)
m.const_ashpcCapa = Constraint(year_i, ts_i, rule = ashpCapac_rule)

def hpbin_rule(m,y,ts):
    return m.b_hph[y,ts] + m.b_hpc[y,ts] <= 1
m.const_hpbin = Constraint(year_i, ts_i, rule = hpbin_rule)

线性:

m.b_hph = Var(year_i, ts_i, within=Binary)

def ashpcons_rule(m,y,ts):
    return sum(m.power[elSup, "heat_pump_air",y, ts] for elSup in elOut) == \
        sum(m.heat["heat_pump_air", hCons, y, ts] for hCons in hIn)/4.5 +\
        sum(m.cool["heat_pump_air", cCons, y, ts] for cCons in cIn)/3.5
m.const_ashpcons = Constraint(year_i,ts_i, rule = ashpcons_rule)

def ashpheatdecision_rule(m,y,ts):
    return sum(m.heat["heat_pump_air", hCons, y, ts] for hCons in hIn) <=\
        99999 * m.b_hph[y,ts] + 0 * (1-m.b_hph[y,ts])
m.const_ashpheatdecision = Constraint(year_i, ts_i, rule = ashpheatdecision_rule)

def ashpcooldecision_rule(m,y,ts):
    return sum(m.cool["heat_pump_air", cCons, y, ts] for cCons in cIn) <=\
        0 * m.b_hph[y,ts] + 99999 * (1-m.b_hph[y,ts])
m.const_ashpcooldecision = Constraint(year_i, ts_i, rule = ashpcooldecision_rule)

def ashpCapah_rule(m,y, ts):
    return sum(m.heat["heat_pump_air", hCons, y, ts] for hCons in hIn) <=\
        m.c_c["heat_pump_air"]
m.const_ashphCapa = Constraint(year_i, ts_i, rule = ashpCapah_rule)

def ashpCapac_rule(m,y, ts):
    return sum(m.cool["heat_pump_air", cCons, y, ts] for cCons in cIn) <=\
        m.c_c["heat_pump_air"] * (3.5/4.5)
m.const_ashpcCapa = Constraint(year_i, ts_i, rule = ashpCapac_rule)

非常感谢您的帮助

阿克塞尔

【问题讨论】:

    标签: optimization mathematical-optimization pyomo mixed-integer-programming


    【解决方案1】:

    而不是写

    h(t) <= M * b(t) 
    c(t) <= M * (1-b(t))
    b(t) ∈ {0,1} 
    

    我会直接使用:

    h(t) <= capacity_h * b(t) 
    c(t) <= capacity_c * (1-b(t))
    b(t) ∈ {0,1} 
    

    一般来说,我们不应该只使用大的 M 值。类似地,对于模型中的其他值 99999。如果您对这些 big-M 没有很好的值,请考虑替代公式,例如指标约束(Pyomo AFAIK 中不可用,但许多求解器都支持)。

    【讨论】:

    • 非常感谢@Erwin。是的,我同意,尽可能避免大女士,但在这种情况下,容量是一个决策变量。因此,这个模型将不再是线性的,不是吗?我可以或多或少估计一下大M的上限(最大需求)。9999只是为了测试。
    猜你喜欢
    • 1970-01-01
    • 2014-04-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-08-27
    • 1970-01-01
    相关资源
    最近更新 更多