m.sum() 是该特定时间点的值的总和。尝试使用m.integral() 来生成时间范围内的总和。使用m.fix_final(c,15) 将积分的最终值固定为15。将m.options.SOLVER=1 与integer=True 一起使用,否则设备可以打开小数值。
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.074646,0.074646,0.074646,\
0.074646,0.074646,0.099206,0.099206,0.099206,0.099206,\
0.169230,0.169230,0.169230,0.169230,0.169230,0.099206,\
0.099206,0.099206,0.099206,0.074646,0.074646,\
0.074646,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 个值的数组。
import numpy as np
from gekko import GEKKO
m = GEKKO()
# Electricity Cost
TOU_list = [0.074646,0.074646,0.074646,0.074646,0.074646,0.074646,\
0.074646,0.099206,0.099206,0.099206,0.099206,\
0.169230,0.169230,0.169230,0.169230,0.169230,0.099206,\
0.099206,0.099206,0.099206,0.074646,0.074646,\
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,lb=0.0, ub=1.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()
因为问题没有微分方程,我推荐第二种方法。