二次约束的线性化 [英] Linearization of quadratic constraint

查看:21
本文介绍了二次约束的线性化的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在我的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:&Q;采暖或制冷模式热泵效率;M:大数值

下面的代码(忽略热泵的技术细节,例如COPS,这些现在已经改变了)。 二次:

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)

非常感谢您的帮助

Axel

推荐答案

而不是写入

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也是类似的。如果您没有这些大M的良好值,请考虑其他公式,如指示器约束(在Pyomo AFAIK中不可用,但许多求解器都支持)。

这篇关于二次约束的线性化的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆