Optimization 如何使用Gekko在离散时间内进行轨迹优化
我正在尝试使用Gekko优化(解除)电池储能系统的充电。每小时的电价Optimization 如何使用Gekko在离散时间内进行轨迹优化,optimization,battery,gekko,discrete,Optimization,Battery,Gekko,Discrete,我正在尝试使用Gekko优化(解除)电池储能系统的充电。每小时的电价EP、太阳能电池板的发电量PV、能源需求Dem,在整个时间范围内(0-24小时)进行考虑,以最小化总成本TC。套利应在电池(dis)充电(Pbat_ch&Pbat_dis)到/从电网(Pgrid_in&Pgrid_out)的最佳时刻进行 与大多数在线示例相反,该问题不是作为状态空间模型来表述的,而是主要依赖于价格、消费和生产的外部数据。下面概述了与Gurobi相关的3个具体问题,导致以下错误的完整代码可以在本文底部找到 Exce
EP
、太阳能电池板的发电量PV
、能源需求Dem
,在整个时间范围内(0-24小时)进行考虑,以最小化总成本TC
。套利应在电池(dis)充电(Pbat_ch
&Pbat_dis
)到/从电网(Pgrid_in
&Pgrid_out
)的最佳时刻进行
与大多数在线示例相反,该问题不是作为状态空间模型来表述的,而是主要依赖于价格、消费和生产的外部数据。下面概述了与Gurobi相关的3个具体问题,导致以下错误的完整代码可以在本文底部找到
Exception: @error: Inequality Definition
invalid inequalities: z > x < y
at0x0000016c6b214040>
STOPPING . . .
这在Gekko中也是可能的,或者这个总和应该被改写成一个积分吗?以下代码正确吗
ElectricityPrice = m.Param([..])
.
.
.
TotalCosts = m.integral(ElectricityPrice*(PowerGridOut - PowerGridIn))
m.Obj(TotalCosts)
m.options.IMODE = 6
m.solve()
m.Equation(SoC.dt() == SoC - 1/(DischargeEfficiency*BatteryCapacity) * Pbattdis - (ChargeEfficiency/BatteryCapacity) * Pbattch)
Demand[t]
和PV[t]
是外部向量,而其他变量是m.MV()
:m = GEKKO()
# horizon
m.time = list(range(0,25))
# data vectors
EP = m.Param(list(Eprice))
Dem = m.Param(list(demand))
PV = m.Param(list(production))
# constants
bat_cap = 13.5
ch_eff = 0.94
dis_eff = 0.94
# manipulated variables
Pbat_ch = m.MV(lb=0, ub=4)
Pbat_ch.DCOST = 0
Pbat_ch.STATUS = 1
Pbat_dis = m.MV(lb=0, ub=4)
Pbat_dis.DCOST = 0
Pbat_dis.STATUS = 1
Pgrid_in = m.MV(lb=0, ub=3)
Pgrid_in.DCOST = 0
Pgrid_in.STATUS = 1
Pgrid_out = m.MV(lb=0, ub=3)
Pgrid_out.DCOST = 0
Pgrid_out.STATUS = 1
#State of Charge Battery
SoC = m.Var(value=0.5, lb=0.2, ub=1)
#Battery Balance
m.Equation(SoC.dt() == SoC - 1/(dis_eff*bat_cap) * Pbat_dis - (ch_eff/bat_cap) * Pbat_ch)
#Energy Balance
m.Equation(((Dem[t] + Pbat_ch + Pgrid_in) == (PV[t] + Pbat_dis + Pgrid_out)) for t in range(0,25))
#Objective
TC = m.Var()
m.Equation(TC == sum(EP[t]*(Pgrid_out-Pgrid_in) for t in range(0,25)))
m.Obj(TC)
m.options.IMODE=6
m.options.NODES=3
m.options.SOLVER=3
m.solve()
很好的应用程序!您可以自己用
m.options.IMODE=3
写出所有离散方程,或者让Gekko为您管理时间维度。当包含目标或约束时,会将其应用于指定的所有时间点。使用m.options.IMODE=6
,不需要在Gekko中添加设置索引,例如[t]
。以下是一个简化模型:
从gekko导入gekko
将numpy作为np导入
m=GEKKO()
#地平线
m、 时间=np.linspace(0,3,4)
#数据向量
EP=m.Param([0.1,0.05,0.2,0.25])
Dem=m.Param([10,12,9,8])
PV=m.Param([10,11,8,10])
#常数
蝙蝠帽=13.5
ch_eff=0.94
dis_eff=0.94
#操纵变量
Pbat_ch=m.MV(lb=0,ub=4)
Pbat_ch.DCOST=0
Pbat_ch.STATUS=1
Pbat_dis=m.MV(lb=0,ub=4)
Pbat_dis.DCOST=0
Pbat_dis.STATUS=1
Pgrid_in=m.MV(lb=0,ub=3)
Pgrid_in.DCOST=0
Pgrid_in.STATUS=1
Pgrid_out=m.MV(磅=0,磅=3)
Pgrid_out.DCOST=0
Pgrid_out.STATUS=1
#蓄电池充电状态
SoC=m.Var(值=0.5,磅=0.2,磅=1)
#电池平衡
m、 方程(bat_cap*SoC.dt()=-dis_eff*Pbat_dis+ch_eff*Pbat_ch)
#能量平衡
m、 方程(Dem+Pbat_ch+Pgrid_in==PV+Pbat_dis+Pgrid_out)
#客观的
m、 最小化(EP*Pgrid_英寸)
#以购买价格的90%出售电力
m、 最大化(0.9*EP*Pgrid_out)
m、 选项。IMODE=6
m、 options.NODES=3
m、 选项。解算器=3
m、 解决()
我修改了你的微分方程,从右边去掉SoC,否则你会得到指数增长。能量平衡微分方程是累积=输入输出
。下面是一些用于可视化解决方案的附加代码
导入matplotlib.pyplot作为plt
plt.子地块(3,1,1)
plt.绘图(m.time,SoC.value,'b--',label='State of Charge')
plt.ylabel(‘SoC’)
plt.legend()
plt.子地块(3,1,2)
plt.plot(m.time,Dem.value,'r--',label='Demand')
plt.plot(m.time,PV.value,'k:',label='PV Production')
plt.legend()
plt.子地块(3,1,3)
plt.plot(m.time,Pbat_ch.value,'g--',label='Battery Charge')
plt.绘图(m.time,Pbat_dis.value,'r:',标签='电池放电')
plt.plot(m.time,Pgrid_in.value,'k--',label='Grid Power in')
plt.plot(m.time,Pgrid_in.value',:',color='橙色',label='Grid Power Out')
plt.ylabel(“电源”)
plt.legend()
plt.xlabel(“时间”)
plt.show()
亲爱的John,非常感谢您快速而详尽的反馈,它确实解决了我无法解决的问题。如果可以的话,我还有一个问题:当应用于我测量的PV和Dem数据(是浮点而不是整数)时,您的模型会导致错误(“问题可能不可行……错误代码为2”)。只有当sum(Dem)=sum(PV)
时,该解决方案才可行。然而,根据定义,情况并非如此:模型必须通过改变Pgrid\u in
/Pgrid\u out
,Pbat\u ch
/Pbat\u dis
(每一对中,任何一对每次都应为零)来确保需求得到满足。我意识到上面的后续问题与主要问题有所不同,因此,我用一个不同的、更直观的例子将其作为一个新问题发布:无论如何,再次感谢您的第一个答案!
m.Equation(SoC.dt() == SoC - 1/(DischargeEfficiency*BatteryCapacity) * Pbattdis - (ChargeEfficiency/BatteryCapacity) * Pbattch)
m.Equation(((Demand[t] + Pbat_ch + Pgrid_in) == (PV[t] + Pgrid_out + Pbat_dis)) for t in range(25))
m = GEKKO()
# horizon
m.time = list(range(0,25))
# data vectors
EP = m.Param(list(Eprice))
Dem = m.Param(list(demand))
PV = m.Param(list(production))
# constants
bat_cap = 13.5
ch_eff = 0.94
dis_eff = 0.94
# manipulated variables
Pbat_ch = m.MV(lb=0, ub=4)
Pbat_ch.DCOST = 0
Pbat_ch.STATUS = 1
Pbat_dis = m.MV(lb=0, ub=4)
Pbat_dis.DCOST = 0
Pbat_dis.STATUS = 1
Pgrid_in = m.MV(lb=0, ub=3)
Pgrid_in.DCOST = 0
Pgrid_in.STATUS = 1
Pgrid_out = m.MV(lb=0, ub=3)
Pgrid_out.DCOST = 0
Pgrid_out.STATUS = 1
#State of Charge Battery
SoC = m.Var(value=0.5, lb=0.2, ub=1)
#Battery Balance
m.Equation(SoC.dt() == SoC - 1/(dis_eff*bat_cap) * Pbat_dis - (ch_eff/bat_cap) * Pbat_ch)
#Energy Balance
m.Equation(((Dem[t] + Pbat_ch + Pgrid_in) == (PV[t] + Pbat_dis + Pgrid_out)) for t in range(0,25))
#Objective
TC = m.Var()
m.Equation(TC == sum(EP[t]*(Pgrid_out-Pgrid_in) for t in range(0,25)))
m.Obj(TC)
m.options.IMODE=6
m.options.NODES=3
m.options.SOLVER=3
m.solve()