如何根据先前设置的索引设置约束

时间:2019-02-18 10:52:24

标签: pyomo

我正在使用Pyomo编写能源优化模型。在此模型中,我有一个约束条件,该约束条件使用上一个时间步长(简化的方程式)中的每个电荷步长来更新能量存储的电荷水平:

Storage_level[t] = Storage_level[t-1] + Charge [t] - Discharge [t]

初始阶段还有一个附加约束:

Storage_level[1] = 0

运行问题时,没有得到任何有用的结果,并且输出窗口仅显示约束范围,例如:

ev_soc_max : Size=24
    Key : Lower : Body : Upper
      1 :  None : None :   0.0
      2 :  None : None :   0.0
      3 :  None : None :   0.0
      4 :  None : None :   0.0
      5 :  None : None :   0.0
      ...

我也得到一些变量的错误:

ERROR: evaluating object as numeric value: p_bat_ch[1]
        (object: <class 'pyomo.core.base.var._GeneralVarData'>)
    No value for uninitialized NumericValue object p_bat_ch[1]

我怀疑问题与存储约束的定义有关。

这就是我在Pyomo中进行编码的方式(通过结合在互联网上到处都是的不同示例,得出了这个结果):

def bat_soc_ini_rule(model, t):
    if t == 1:
        return model.e_bat_t[t] == 0.
    else:
        return Constraint.Skip
model.bat_soc_ini = Constraint(model.T, rule = bat_soc_ini_rule)

def bat_soc_rule(model, t):
    if t >= 2:
        return model.e_bat_t[t] == model.eta_bat_cal * model.e_bat_t[t-1] + model.eta_bat_ch * model.p_bat_ch[t] - model.eta_bat_dis**-1 * model.p_bat_dis[t]
    else:
        return Constraint.Skip
model.bat_soc = Constraint(model.T, rule = bat_soc_rule)

我还应该声明我使用model.T声明了model.T = RangeSet(24)集,并且变量声明如下:model.e_bat_t = Var(model.T, within = NonNegativeReals)

最后一点:我正在使用GLPK作为求解器。

我的问题是:

  1. 我应该如何声明一个调用集合中前一个成员的约束?我做对了吗?

  2. 我应该如何仅对集合的一部分设置约束(例如,针对初始化约束)?

  3. 我是否认为错误来自此约束的错误定义?如果没有,您是否知道问题可能来自何处?

1 个答案:

答案 0 :(得分:0)

好吧,我正在使用urbs atm,并从中获得以下代码。

这是您要寻找的约束规则storage[t] = storage[t-1] + in - out

# storage content in timestep [t] == storage content[t-1] * (1-discharge)
# + newly stored energy * input efficiency
# - retrieved energy / output efficiency
def def_storage_state_rule(m, t, sit, sto, com):
    return (m.e_sto_con[t, sit, sto, com] ==
            m.e_sto_con[t-1, sit, sto, com] *
            (1 - m.storage_dict['discharge'][(sit, sto, com)]) ** m.dt.value +
            m.e_sto_in[t, sit, sto, com] *
            m.storage_dict['eff-in'][(sit, sto, com)] -
            m.e_sto_out[t, sit, sto, com] /
            m.storage_dict['eff-out'][(sit, sto, com)])

对于设置init值,它们具有以下内容:

# initialization of storage content in first timestep t[1]
# forced minimun  storage content in final timestep t[len(m.t)]
# content[t=1] == storage capacity * fraction <= content[t=final]
def res_initial_and_final_storage_state_rule(m, t, sit, sto, com):
    if t == m.t[1]:  # first timestep (Pyomo uses 1-based indexing)
        return (m.e_sto_con[t, sit, sto, com] ==
                m.cap_sto_c[sit, sto, com] *
                m.storage_dict['init'][(sit, sto, com)])
    elif t == m.t[len(m.t)]:  # last timestep
        return (m.e_sto_con[t, sit, sto, com] >=
                m.cap_sto_c[sit, sto, com] *
                m.storage_dict['init'][(sit, sto, com)])
    else:
        return pyomo.Constraint.Skip

希望此示例对您有所帮助。您可以使用它来更改它或在您的代码中对其进行修改-