You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Gekko中Time Delay(m.delay)原理及代码运行异常问题咨询

问题与解答

技术问题咨询

我查阅了APMonitor中的Time Delay方法,并结合Gekko的m.Intermediate方法编写了如下代码,现存在两个技术问题:

  1. 根据代码中的m.delay(B_SOC_initial, B_SOC_Prev, 1),预期B_SOC_Prev[1]等于B_SOC_initial[0],但实际结果为0,请指出问题所在。
  2. 定义目标函数c[i] = Generation以最大化c[i]的总和,但结果返回的是所有迭代中c[i]的总和而非最优值,预期目标函数值为103000,实际得到309000。

代码实现

from gekko import GEKKO
import numpy as np

#Battery Specifications
Battery_capacity=589200 #kW-h
Battery_Initial_capacity=117840

n=3
m = GEKKO(remote=False)
m.time = np.linspace(0, n - 1, n)

Demand =m.Param([0,46258,46952])
Generation =m.Param([0,53000,50000])

B_ch = m.Var(lb=0)
B_disch = m.Var(lb=0)

B_SOC_Prev= m.Var(value=Battery_Initial_capacity)
B_SOC_initial=m.Intermediate(B_SOC_Prev+B_ch-B_disch)
m.delay(B_SOC_initial, B_SOC_Prev, 1)

m.Equations([Generation + B_disch - B_ch == Demand,
             B_disch * B_ch <= 0,
             ]
            )

c = [None]*(n)
for i in range(n):
    c[i] = Generation

m.Maximize(sum(c))

m.solver_options = ['minlp_gap_tol 1.0e-2',\
                    'minlp_maximum_iterations 10000',\
                    'minlp_max_iter_with_int_sol 500',\
                    'minlp_branch_method 1',\
                    'minlp_integer_tol 1e-8', \
                    'minlp_integer_leaves 2']
m.options.SOLVER   = 1
m.options.IMODE    = 6

# m.open_folder()
m.solve(disp=False)

print("Obj. Value=",-m.options.OBJFCNVAL)

for i in range(n):
    print("B_ch[{}]={} B_disch[{}]={} B_SOC_initial[{}]={}  B_SOC_Prev[{}]={}".format(i,B_ch[i],i,B_disch[i], i,B_SOC_initial[i],i,B_SOC_Prev[i]))

问题解答

问题1:延迟变量初始值错误

m.delay()函数默认会将延迟变量的初始条件设为0,覆盖了你给B_SOC_Prev设定的初始值Battery_Initial_capacity。解决方法是在调用m.delay()时通过init参数指定初始值,同时调整变量定义顺序确保逻辑正确:

# 先定义中间变量,再创建延迟变量并指定初始值
B_SOC_Prev = m.Var(value=Battery_Initial_capacity)
B_SOC_initial = m.Intermediate(B_SOC_Prev + B_ch - B_disch)
m.delay(B_SOC_initial, B_SOC_Prev, 1, init=Battery_Initial_capacity)

这样就能保证B_SOC_Prev[1]等于B_SOC_initial[0],初始值也不会被覆盖。

问题2:目标函数计算错误

Generation是m.Param类型的固定参数,你在循环中c[i] = Generation相当于把整个Generation数组重复添加了n次,最终总和变成3*(0+53000+50000)=309000。如果要最大化各时间步Generation的总和,直接对Generation求和即可,无需循环赋值:

m.Maximize(sum(Generation))

如果你的实际需求是优化Generation的值(当前代码中它是固定参数无法优化),需要先将其改为m.Var类型并添加对应约束,再最大化其总和。

内容的提问来源于stack exchange,提问作者Reza_nadimi

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.01 12:30:21