如何在 Gekko 中对依赖于时间的约束进行建模?

问题描述

我是 Python 中 Gekko 库的新手,想知道是否可以在 Gekko 中对以下 LP 公式进行建模。

LP Formulation

LP 公式意味着我想找到最优的电器调度班次,以使总电力成本最小化。但是,如约束所示,每天的总耗电量 (f_apP*P_app) 必须保持一致。

我的代码如下所示,但是我收到以下错误“x 必须是 GEKKO 参数、变量或表达式的 Python 列表”,我不知道如何解决

代码

import numpy as np
from gekko import GEKKO

m = GEKKO()
m.time = np.linspace(1,24,24)

TOU_list = [0.074646,0.074646,\
            0.074646,0.099206,\
            0.169230,0.169230,\
            0.099206,0.074646] # Electricity Cost
        
TOU = m.Param(value= TOU_list)
P_app = 10.5 # Appliance power (kW)
f_app = m.MV(lb=0.0,ub=1.0,integer=False) # electric appliance schedule (0-1)

m.Equation(m.sum(f_app) == 15) # Summation of the appliance schedule for 24 hour time horizon         

m.Minimize(TOU*f_apP*P_app)

m.options.IMODE = 6
m.options.soLVER = 3
m.solve(disp=True,GUI=False)

解决方法

m.sum() 是该特定时间点的值的总和。尝试使用 m.integral() 来生成时间范围内的总和。使用 m.fix_final(c,15) 将积分的最终值固定为 15。将 m.options.SOLVER=1integer=True 一起使用,否则设备可以打开为小数值。

Electricity Usage

import numpy as np
from gekko import GEKKO

m = GEKKO()
m.time = np.linspace(0,24,25)

# Electricity Cost
TOU_list = [0.074646,0.074646,\
            0.074646,0.099206,\
            0.169230,0.169230,\
            0.099206,0.074646] 
        
TOU = m.Param(value= TOU_list)
P_app = 10.5 # Appliance power (kW)
# electric appliance schedule (0-1)
f_app = m.MV(value=0,lb=0.0,ub=1.0,integer=True)
f_app.STATUS = 1

# Summation of the appliance schedule for 24 hour time horizon
c = m.integral(f_app)
m.fix_final(c,15)

m.Minimize(TOU*f_app*P_app)

m.options.IMODE = 6
m.options.SOLVER = 1
m.solve(disp=True,GUI=False)

import matplotlib.pyplot as plt
plt.plot(m.time,f_app.value,label='On / Off')
plt.plot(m.time,TOU_list,label='Electricity Cost')
plt.legend()
plt.show()

我在开始时添加了一个额外的时间点,因为它是 24 小时,总共 25 个时间点。如果有 1 小时,那么优化问题需要有两个时间点来定义开始和结束。 24小时,需要25分。

您可以通过使用 m.Array() 对 24 个时间段进行编程来避免动态控制模式的一些复杂性。这样您就可以使用 m.sum(),因为 f_app 是一个包含 24 个值的数组。

Solution - discrete

import numpy as np
from gekko import GEKKO

m = GEKKO()

# Electricity Cost
TOU_list = [0.074646,0.074646] 
n = len(TOU_list)
        
P_app = 10.5 # Appliance power (kW)
# electric appliance schedule (0-1)
f_app = m.Array(m.Var,n,value=0,integer=True)

# Summation of the appliance schedule for 24 hour time horizon
m.Equation(m.sum(f_app)==15)

for i in range(n):
    m.Minimize(TOU_list[i]*f_app[i]*P_app)

m.options.IMODE = 3
m.options.SOLVER = 1
m.solve(disp=True)

f = []
t = []
for i in range(n):
    t.append(i+1)
    f.append(f_app[i].value[0])

import matplotlib.pyplot as plt
plt.bar(x=t,height=f,label='On / Off')
plt.bar(x=t,height=TOU_list,label='Electricity Cost')
plt.legend()
plt.show()

因为问题没有微分方程,所以我推荐第二种方法。