使用 pyomo 进行线性优化

Linear optimization with pyomo

我最近开始尝试学习 python 以解决线性优化问题。 我正在努力将家庭的二氧化碳排放量降至最低。求解器应该在从电网获取电力(包括一定量的二氧化碳)和光伏发电之间做出选择。 可悲的是,我似乎太愚蠢了,无法正确解决问题,求解器对 8 个时间步长中的每一个都不断计算它 8 次(时间步长的数量)。

这是一个只有 8 个时间步长的测试版本,只是为了测试我是否能够将它从 excel 中提取出来,而不是自己手动输入字典。

如前所述,该程序应该通过在电网电力(“导入”)和光伏电力(“Eigenproduktion”)之间进行选择来始终等于需求。 它还应该在 8 小时的时间内完成。

data = pd.read_excel(Stromsimulation, skiprows = 1, usecols=('A:E'), index_col = 0)
df = pd.DataFrame(data)
daten = df.to_dict()
model = ConcreteModel()

model.n = RangeSet(1, 8)

model.verbrauch = Param(model.n, initialize = daten['Verbrauch'])
model.eigenproduktion = Param(model.n, initialize = daten['Eigenproduktion'])
model.stromimport = Param(model.n, initialize = daten['Import'])
model.emissionen = Param(model.n, initialize = daten['CO2-Emissionen'])

model.x = Var(model.n, within = NonNegativeReals)

def emissionsreduzierung(model, t):
  return sum(((model.x[t] * model.stromimport[t]) * model.emissionen[t] for t in model.n))
model.emissionsreduzierung = Objective(rule = emissionsreduzierung, sense = minimize)

def lastdeckung(model, t):
  return (sum(model.eigenproduktion[t] + (model.stromimport[t] * model.x[t]) for t in model.n) == model.verbrauch[t])
model.lastdeckung = Constraint(model.n, rule = lastdeckung)

出于某种原因,它一直这样做:

1 Objective Declarations
    emissionsreduzierung : Size=1, Index=None, Active=True
        Key  : Active : Sense    : Expression
        None :   True : minimize : 30.0*x[1] + 15.0*x[2] + 45.0*x[3] + 30.0*x[4] + 22.5*x[5] + 49.5*x[6] + 52.5*x[7] + 60.0*x[8]

1 Constraint Declarations
    lastdeckung : Size=8, Index=n, Active=True
        Key : Lower : Body                                                                                                                       : Upper : Active
          1 :  30.0 : 5 + 150*x[1] + 8 + 150*x[2] + 9 + 150*x[3] + 10 + 150*x[4] + 15 + 150*x[5] + 21 + 150*x[6] + 30 + 150*x[7] + 25 + 150*x[8] :  30.0 :   True
          2 :  25.0 : 5 + 150*x[1] + 8 + 150*x[2] + 9 + 150*x[3] + 10 + 150*x[4] + 15 + 150*x[5] + 21 + 150*x[6] + 30 + 150*x[7] + 25 + 150*x[8] :  25.0 :   True
          3 :  35.0 : 5 + 150*x[1] + 8 + 150*x[2] + 9 + 150*x[3] + 10 + 150*x[4] + 15 + 150*x[5] + 21 + 150*x[6] + 30 + 150*x[7] + 25 + 150*x[8] :  35.0 :   True
          4 :  61.0 : 5 + 150*x[1] + 8 + 150*x[2] + 9 + 150*x[3] + 10 + 150*x[4] + 15 + 150*x[5] + 21 + 150*x[6] + 30 + 150*x[7] + 25 + 150*x[8] :  61.0 :   True
          5 :  42.0 : 5 + 150*x[1] + 8 + 150*x[2] + 9 + 150*x[3] + 10 + 150*x[4] + 15 + 150*x[5] + 21 + 150*x[6] + 30 + 150*x[7] + 25 + 150*x[8] :  42.0 :   True
          6 :  31.0 : 5 + 150*x[1] + 8 + 150*x[2] + 9 + 150*x[3] + 10 + 150*x[4] + 15 + 150*x[5] + 21 + 150*x[6] + 30 + 150*x[7] + 25 + 150*x[8] :  31.0 :   True
          7 :  54.0 : 5 + 150*x[1] + 8 + 150*x[2] + 9 + 150*x[3] + 10 + 150*x[4] + 15 + 150*x[5] + 21 + 150*x[6] + 30 + 150*x[7] + 25 + 150*x[8] :  54.0 :   True
          8 :  32.0 : 5 + 150*x[1] + 8 + 150*x[2] + 9 + 150*x[3] + 10 + 150*x[4] + 15 + 150*x[5] + 21 + 150*x[6] + 30 + 150*x[7] + 25 + 150*x[8] :  32.0 :   True

您的主要问题如下:lastdeckung 约束构造了 8 次,因为当您像 Constraint(model.n, rule = lastdeckung) 那样调用它时就会发生这种情况:这转化为“对于每个 n(时隙),调用函数lastdeckung”。这就是您想要的,因为能量平衡方程需要在每个小时内保持不变。但是,同时您要添加所有时隙的能量项 nsum(... for t in model.n)。那没有意义。相反,使用传递给函数的 t 来定义给定时隙的约束:

def lastdeckung(model, t):
  return model.eigenproduktion[t] + (model.stromimport[t] * model.x[t]) == model.verbrauch[t]
model.lastdeckung = Constraint(model.n, rule = lastdeckung)