使用 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
”。这就是您想要的,因为能量平衡方程需要在每个小时内保持不变。但是,同时您要添加所有时隙的能量项 n
:sum(... 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)
我最近开始尝试学习 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
”。这就是您想要的,因为能量平衡方程需要在每个小时内保持不变。但是,同时您要添加所有时隙的能量项 n
:sum(... 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)