如何用Gekko优化电动汽车充电成本?代码报错求解
问题分析与修复
你遇到的错误是代码里几个关键的Gekko使用逻辑错误导致的,包括变量赋值、方程传递、索引逻辑和目标函数的问题,下面是具体修复步骤和修正后的代码:
核心错误点
- 不能直接给Gekko变量赋值:
SOC_t[0,0] = 30这种写法错误,必须用m.fix()固定初始值 - 方程传递方式错误:
m.Equation()不能直接传列表,要用m.Equations()(复数形式)接收方程列表 - 变量索引错误:当
Num_car=1时,SOC_t[tt]和p_i[tt]是一维数组,应该用SOC_t[tt,0]和p_i[tt,0]取单个变量 - SOC目标逻辑错误:原代码想让最终SOC达到最大值,不是所有时刻SOC之和,应该取最后时刻的SOC值
- 目标函数变量索引错误:
p_i[i]是数组,需要指定具体的车辆索引p_i[i,0]
修正后的代码
from gekko import GEKKO import numpy as np import matplotlib.pyplot as plt m = GEKKO() m.options.SOLVER = 1 # APOPT求解器 m.options.IMODE = 3 # 稳态优化模式 Num_car = 1 # 24小时分时电价 TOU = [64.9,64.9,64.9,64.9,64.9,64.9,64.9,64.9,152.6,239.8,239.8,152.6,239.8,239.8,239.8,239.8,152.6,152.6,152.6,152.6,152.6,152.6,152.6,64.9] n = len(TOU) # 放电功率变量:[时间,车辆],下限0 p_i = m.Array(m.Var, (n, Num_car), lb=0) # 充电功率变量:整数型,0-7kW input = m.Array(m.Var, n, value=0.0, lb=0.0, ub=7.0, integer=True) # SOC状态变量:[时间,车辆] SOC_t = m.Array(m.Var, (n, Num_car)) # 设置SOC上下限 for tt in range(n): for i in range(Num_car): SOC_t[tt,i].lower = 30 SOC_t[tt,i].upper = 70 # 固定初始SOC为30 m.fix(SOC_t[0,0], 30) # 构建SOC变化方程:下一刻SOC = 当前SOC + 充电功率 - 放电功率 eq_car_bat = [] for tt in range(n-1): # n个时刻对应n-1个状态变化方程 eq_car_bat.append(SOC_t[tt+1,0] == SOC_t[tt,0] + input[tt] - p_i[tt,0]) # 添加最终SOC约束:最后时刻SOC达到最大值90 eq_car_bat.append(SOC_t[-1,0] == 90) # 批量添加方程 m.Equations(eq_car_bat) # 目标函数:最小化总充电成本(若p_i是需付费的功率,可改为TOU[i]*p_i[i,0]) for i in range(n): m.Minimize(TOU[i] * input[i]) # 求解优化问题 m.solve(disp=True) # 输出结果 print("充电功率:", [input[i].value[0] for i in range(n)]) print("SOC变化:", [SOC_t[i,0].value[0] for i in range(n)]) # 可视化结果 plt.figure(figsize=(12,6)) plt.subplot(2,1,1) plt.plot(TOU, label='分时电价') plt.ylabel('电价') plt.legend() plt.subplot(2,1,2) plt.plot([input[i].value[0] for i in range(n)], label='充电功率') plt.plot([SOC_t[i,0].value[0] for i in range(n)], label='SOC') plt.xlabel('小时') plt.ylabel('数值') plt.legend() plt.show()
额外说明
- 原代码的方程逻辑不符合SOC变化的物理意义,修正为下一时刻SOC = 当前SOC + 充电功率 - 放电功率,如果你的
p_i是充电功率,需要调整方程逻辑 - 目标函数默认按充电成本最小化设置,可根据实际需求替换为对应付费功率项
- 使用
m.Equations()(复数形式)是Gekko批量添加方程的正确方式 - Gekko变量的初始值固定必须用
m.fix(),不能直接赋值
内容的提问来源于stack exchange,提问作者LAP1040400
相关产品推荐
相关产品推荐

