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

CVXPy凸优化在工商业光储系统优化中未达最优性能的问询

工商业光储系统CVXPy凸优化方案改进建议

问题概述

我正在优化一套由1MWh电池系统与200kW额定容量光伏组成的工商业光储系统,核心目标是降低建筑电费。工商业电费包含两部分:

  • 基于月度总能耗的能源费
  • 基于15分钟间隔峰值用电量的需求费
    费率采用分时计价(TOU)策略。

优化方向为最小化月度能耗以削减能源费,同时通过电池储电平抑用电尖峰、降低需求费,理想运行逻辑是:光伏出力过剩时给电池充电,负载需求过剩时电池放电补能。目前负载跟随算法已实现接近理想的优化效果,但采用CVXPy凸优化方案时性能极差——甚至比不使用电池的情况更糟,能源消耗增加且需求费上升。已排查代码、目标函数与约束条件,未发现明显问题,推测可能是求解器优先将过剩电力并网导致尖峰出现,特此寻求改进建议。


附:翻译后的代码

凸优化CVXPy代码及输出(中文翻译版)

# 导入CVXPy库
import cvxpy as cp

# 基础参数定义
time_step = 0.25  # 时间步长:15分钟(0.25小时)
num_steps = 2880  # 月度总时间步数(按30天计算:30*24/0.25)

# 优化变量定义
grid_purchase = cp.Variable(num_steps, nonneg=True)  # 电网购电功率(kW)
pv_output = cp.Parameter(num_steps, nonneg=True)     # 光伏出力(kW,已知输入)
load_demand = cp.Parameter(num_steps, nonneg=True)   # 负载需求(kW,已知输入)
battery_charge = cp.Variable(num_steps, nonneg=True) # 电池充电功率(kW)
battery_discharge = cp.Variable(num_steps, nonneg=True) # 电池放电功率(kW)
soc = cp.Variable(num_steps+1, nonneg=True)          # 电池荷电状态(SOC,kWh)
peak_demand = cp.Variable(nonneg=True)               # 15分钟最大用电峰值(kW)

# 费率参数
energy_rates = cp.Parameter(num_steps)  # 分时能源费率(元/kWh)
demand_rate = cp.Parameter()            # 需求费费率(元/kW)

# 目标函数:最小化月度总电费(能源费+需求费)
objective = cp.Minimize(
    cp.sum(grid_purchase * time_step * energy_rates) + demand_rate * peak_demand
)

# 约束条件
constraints = []
# 功率平衡:电网购电 + 光伏出力 + 电池放电 = 负载需求 + 电池充电
constraints += [
    grid_purchase[i] + pv_output[i] + battery_discharge[i] == load_demand[i] + battery_charge[i]
    for i in range(num_steps)
]
# 电池功率限制:充电/放电功率不超过额定值(假设为200kW)
constraints += [battery_charge[i] <= 200 for i in range(num_steps)]
constraints += [battery_discharge[i] <= 200 for i in range(num_steps)]
# SOC约束:初始与结束SOC一致(月度循环),SOC范围0~1000kWh
constraints += [soc[0] == soc[-1]]
constraints += [soc[i] >= 0 for i in range(num_steps+1)]
constraints += [soc[i] <= 1000 for i in range(num_steps+1)]
# SOC变化逻辑:SOC(t+1) = SOC(t) + (充电功率-放电功率)*时间步长
constraints += [
    soc[i+1] == soc[i] + (battery_charge[i] - battery_discharge[i]) * time_step
    for i in range(num_steps)
]
# 峰值需求约束:每个时间步的电网购电不超过峰值
constraints += [grid_purchase[i] <= peak_demand for i in range(num_steps)]

# 求解优化问题
prob = cp.Problem(objective, constraints)
prob.solve(solver=cp.GUROBI)

# 输出结果
print("月度总电费:", prob.value)
print("峰值需求:", peak_demand.value)

负载跟随算法代码(中文翻译版)

# 基础参数初始化
time_step = 0.25          # 时间步长:15分钟
battery_capacity = 1000   # 电池额定容量:1MWh
max_charge_power = 200    # 电池最大充电功率:200kW
max_discharge_power = 200 # 电池最大放电功率:200kW
initial_soc = 500         # 初始SOC:500kWh
soc = initial_soc
total_grid_energy = 0     # 月度电网购电总量(kWh)
peak_demand = 0           # 15分钟用电峰值(kW)

# 遍历每个时间步执行负载跟随逻辑
for i in range(len(pv_output_data)):
    pv = pv_output_data[i]
    load = load_demand_data[i]
    net_load = load - pv  # 净负载:需求-光伏出力

    charge = 0
    discharge = 0
    if net_load < 0:
        # 光伏过剩,优先给电池充电
        available_charge = -net_load
        max_possible_charge = min(max_charge_power, (battery_capacity - soc)/time_step)
        charge = min(available_charge, max_possible_charge)
        soc += charge * time_step
        # 剩余过剩电力并网(若允许)
        grid_export = available_charge - charge
    else:
        # 负载过剩,优先电池放电补能
        needed_discharge = net_load
        max_possible_discharge = min(max_discharge_power, soc/time_step)
        discharge = min(needed_discharge, max_possible_discharge)
        soc -= discharge * time_step
        # 不足部分从电网购电
        grid_import = needed_discharge - discharge
        total_grid_energy += grid_import * time_step
        # 更新峰值需求
        if grid_import > peak_demand:
            peak_demand = grid_import

# 计算月度总电费
total_cost = total_grid_energy * average_energy_rate + peak_demand * demand_rate
print("月度总电费:", total_cost)
print("峰值需求:", peak_demand)

改进建议

1. 修正目标函数的优先级与逻辑

当前目标函数可能因权重分配不合理,导致求解器优先选择并网(若有收益)而非储电削峰。建议:

  • 若并网收益远低于需求费支出,直接在目标函数中移除并网收益项,或添加惩罚项抑制并网行为;
  • 采用分层优化逻辑:先添加约束锁定峰值需求上限,再最小化能源费,避免求解器为小额收益牺牲峰值控制。

2. 添加约束限制过剩电力并网

针对“求解器优先并网导致尖峰”的推测,可通过约束强制优先储电:

  • 若不需要并网,直接添加grid_export = 0(或在功率平衡中移除并网变量),强制过剩光伏全部用于电池充电(在电池容量/功率限制内);
  • 若允许并网,设置并网功率上限(如grid_export[i] <= 50),降低求解器选择并网的优先级。

3. 明确需求费的计算基准

需求费的计算基准(电网购电峰值/建筑总用电峰值)直接影响约束逻辑,需确认后修正:

  • 若需求费基于电网购电峰值,约束grid_purchase[i] <= peak_demand是正确的;
  • 若基于建筑总用电峰值,需将约束改为load_demand[i] <= peak_demand + pv_output[i] + battery_discharge[i],避免求解器通过电网购电补能推高峰值。

4. 优化求解器设置与验证

  • 更换求解器:尝试使用GUROBI、CPLEX等商业求解器(默认ECOS可能在复杂问题上表现不佳),不同求解器的优化策略差异可能解决当前问题;
  • 开启求解器日志:设置solver=cp.GUROBI, verbose=True,查看求解过程中变量的取值变化,定位是否存在异常并网或电池充放电行为;
  • 添加正则项:对电池充放电功率的变化率添加约束(如battery_charge[i+1] - battery_charge[i] <= 50),避免求解器出现极端充放电操作。

5. 验证凸性与约束合理性

确保整个优化问题是严格凸的:

  • 将peak_demand变量替换为cp.max(grid_purchase)(CVXPy支持cp.max作为凸函数),避免手动定义峰值变量可能导致的非凸问题;
  • 检查所有约束是否为线性或凸约束,排除非凸等式/不等式(如绝对值、平方项的错误使用)。

内容的提问来源于stack exchange,提问作者Luis Enriquez-Contreras

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.21 21:33:09