资讯动态

风光储互补调度:Matlab下电池与矿井抽蓄联合优化

发布时间:2026/10/3 10:22:59 来源:尧图企业网站定制
风电、光伏与储能互补调度这个方向最近几年在各类项目申报和论文里出现的频率非常高。原因不复杂——风电和光伏的出力天然不稳定靠单一电源根本没法满足负荷侧的连续可靠供电必须引入储能来削峰填谷和平滑波动。我这次做的是把电池储能和废弃矿井小型抽水蓄能放在同一个调度框架里用Matlab把它们和风电、光伏联合起来做互补运行优化。整体思路是风、光出力优先消纳储能设备在剩余空间里调节功率和电量最终目标是系统运行成本最小、可再生能源利用率够高。下面把整个项目的建模思路、代码实现过程和一些踩过的坑整理出来给正在做类似研究的同行一些参考。这个课题的核心难点不在于某个单一模型而在于怎么把四类特性差异很大的设备放进一个统一调度框架里。风力发电跟着气象走光伏输出呈明显的钟形曲线电池储能响应快但容量有限抽水蓄能响应慢但单次循环的能量吞吐量大。把这四者放在一起优化本质上是在做一个带时序耦合约束的多能源协调问题。我选择用Matlab来实现主要看中它在矩阵运算、约束建模和结果可视化上的整合效率后期如果要改成鲁棒优化或随机规划也不用推翻重来。1. 项目解读为什么风光储一定要做互补而不是拼接很多初学者拿到这类题目第一反应是我分别建一个风电模型、一个光伏模型、一个储能模型然后把它们接在一起不就行了吗。这个思路看着对实际做出来结果往往很差。原因在于互补调度不是设备层面的物理连接而是运行层面的时序协同。1.1 风光出力的天然缺陷与储能的调节价值先看一组典型特征。风电出力在时间尺度上表现为强随机性强波动性我实测过西北某风电场的数据相邻15分钟的出力量最大可以差到装机容量的40%。光伏则更规律一些白天出力高、夜间为零、阴天时整体下移但它的问题同样明显——和负荷高峰的匹配度不稳定夏天午后光伏出力峰值和傍晚负荷峰值之间存在明显的时间错位。这两类电源叠加之后系统净负荷曲线仍然会出现两个典型问题一个是净负荷爬坡率过高另一个是净负荷的峰谷差过大。储能装置在这里承担的角色就是把这根净负荷曲线掰平低负荷高出力时充电把多余电量存起来高峰负荷或出力快速跌落时放电把功率缺口补上。如果只用电池或者只用抽水蓄能要么受制于容量上限要么受制于响应速度所以混合储能是更合理的方案。1.2 为什么把电池和废弃矿井抽水蓄能放在一起电池储能和抽水蓄能不是替代关系而是互补关系。我用下表来对比两者的运行特性特性维度电池储能废弃矿井小型抽水蓄能响应速度毫秒级到秒级分钟级能量密度高场地占用小低但规模可以做得很大循环寿命受充放电深度影响衰减明显机械寿命长水工设施维护成本低日循环次数可以做到多次深度充放受水泵水轮机启停限制一般一天1~2次辅助功能一次调频、二次调频、电压支撑削峰填谷、黑启动、紧急备用建设条件选址灵活模块化扩展需要废弃矿井的上下巷道空间形成水位差从调度层面看电池负责快的部分——短期内平抑波动、跟踪计划出力抽水蓄能负责大的部分——在更长的时间尺度上搬运能量把午间的富余光伏电量存到傍晚高峰期放出来。两者配合得好可以实现功率尺度和能量尺度的双重平衡。关于废弃矿井小型抽水蓄能的概念我想多说明一下。它利用的是废弃矿井中残留的巷道空间和竖井上水平巷道作为上水库下水平巷道作为下水库中间利用井筒的高度差形成水头。相比传统的大型抽水蓄能电站它不需要新建两个大型水库对地形条件的需求低很多。当然它也有限制——水头一般只有几十米到一百多米单机容量也就几百千瓦到几兆瓦所以叫做小型抽水蓄能。但架不住它量大一个矿区如果有多对井筒组合起来的调节能力相当可观。1.3 这个项目到底在调度什么把问题抽象一层互补调度运行研究回答的核心问题是两句话在任意时刻风电、光伏、电池、抽水蓄能各自的出力或功率应该设多少才能让系统在满足负荷的前提下运行成本最低或者新能源消纳率最高。这是一个典型的多时段、多设备、带时序耦合的优化问题。决策变量包含了每个时段各电源的出力、储能设备的充放电功率、启停状态等而约束条件则涉及功率平衡、设备出力上下限、储能SOC动态过程、抽水蓄能库容变化等。时间粒度我一般取1小时或15分钟调度周期可以取24小时或者更长。之前有人问我这么多个目标到底优化哪个好。我的建议是不要把经济性最优和新能源消纳率最高同时塞进目标函数搞加权这两个目标在量纲和方向上都会打架。更务实的做法是以运行成本最小为目标在约束条件里加入弃风弃光率上限或者反过来以消纳率最大为目标、把成本作为约束效果都会比加权清晰很多。我的模型里选择的是前者——经济性目标为主消纳率用约束托底。2. 核心模型从物理过程到数学约束这部分是整个研究的地基。模型建得不合理后面求解器再强大也算不出有意义的结果。我按照风电、光伏、电池、抽水蓄能四类设备来分别说明建模方法然后补充它们之间的耦合关系。2.1 风力发电出力模型风电出力的物理基础是风能转化为机械能再转化为电能。理论上风电机组的输出功率和风速的三次方成正比但实际机组都有切入风速、额定风速和切出风速的限制所以出力必须分段表示风速低于切入风速时出力为0风速在切入风速和额定风速之间时出力按近似三次方曲线爬升风速在额定风速和切出风速之间时出力恒等于额定功率风速超过切出风速时为了保护机组出力降为0。这套分段函数在Matlab里实现非常方便可以用逻辑索引快速计算整个时间序列的出力。有一点要注意的是风电场的实际出力还会受尾流效应、机组可利用率等因素影响所以更精细的模型会在理论出力曲线上乘以一个折减系数一般在0.9~0.95之间。如果你用的是历史出力数据那这些因素已经包含在数据里了不需要再额外折减。从调度角度看风电出力在短期内不可控所以通常作为负的负荷处理——即优先消纳不够的部分由其他电源补足多余的部分弃掉或者给储能充电。模型中会设置一个风电预测出力值实际消纳量不超过该值二者之差就是弃风量。2.2 光伏发电出力模型光伏出力的核心物理过程是光伏效应。标准化的出力模型是先算太阳辐照度再乘上光伏阵列面积和光电转换效率。辐照度的日变化可以近似用正弦曲线描述但实际中云量、气温、组件衰减都会影响结果。有的模型把温度对效率的影响也考虑进去温度升高时组件输出电压下降出力反而降低这是硅基组件的常见现象。在调度模型中光伏和风电类似也是优先消纳的电源。需要额外注意的是光伏出力的一次性特征——它白天发的电如果当时用不掉没法像风电那样留到晚上所以光伏和储能的时间配合尤其重要。午间光伏高发时段储能充电傍晚光伏跌落而负荷还在高位时储能放电这个时序匹配是模型中必须要能体现的。我之前在建模时就踩过一个坑把光伏出力当成和风电一样的全天候可调度电源来处理结果优化结果非常离谱——深夜时段还在给电池大量充电而这些电根本无处可去。后来把光伏的时序特征完整写进约束里结果才合理。2.3 电池储能系统建模电池储能模型的核心变量是荷电状态SOCState of Charge它描述当前剩余容量占额定容量的百分比。充放电过程中SOC按以下离散递推关系更新SOC(t1) SOC(t) eta_ch * P_ch(t) * dt / E_rated - P_dis(t) * dt / (eta_dis * E_rated)其中P_ch和P_dis是充放电功率eta_ch和eta_dis是充放电效率E_rated是额定容量dt是时间步长。很多初学者会忽略一个关键点SOC公式中充放电效率的位置不一样。充电时电网输入的电能有一部分会转化成热量损耗所以实际存入电池的电量小于输入电量效率乘在功率上放电时电池放出的电量小于实际输出到电网的电量效率是除在功率上。把效率位置放错会导致SOC计算出现系统性偏差。电池模型还需要考虑以下约束充放电功率上限受电池额定功率和变流器容量限制SOC上下限实际使用中一般不允许SOC到0或100%通常限制在10%~90%区间过放会损伤电池过充有安全隐患充放电互斥同一时刻不能同时充电和放电这个在模型中可以用二进制变量来约束电池还有一个容易被忽视的问题——循环寿命衰减。频繁的深度充放电会加速电池老化所以在长期运行模拟中通常要加一个DOD放电深度相关的寿命损耗项。我在项目中简化为对单次充放电循环次数的限制更精细的做法是把寿命损耗折算成成本加入目标函数这样调度算法会自动避免过于频繁的深度充放电。2.4 废弃矿井小型抽水蓄能建模抽水蓄能的建模比电池复杂一些因为它涉及两个水位之间的水量转换物理过程不能简化为一个SOC的递推。核心状态量是上水库的蓄水量V其动态方程为V(t1) V(t) eta_p * P_pump(t) * dt - P_gen(t) * dt / eta_genP_pump是抽水工况下的耗电功率P_gen是发电工况下的输出功率eta_p和eta_gen分别对应水泵和发电机的效率。从形式上看这跟电池的SOC递推很像但实际建模时差异很大第一抽水蓄能的充放电效率受水头影响。水头越高单位水量对应的能量越大但水头本身又随着库容变化而变化。严格的做法是建立水头-库容-功率的三维关系表但这会引入非线性约束增加求解难度。我在项目中采用了等值效率法把整个循环的效率折算成常数简化但物理上仍然是可信的。第二抽水蓄能一般有最小技术出力要求。水泵和发电机组在高转速工况下效率较高不能长期工作在极低功率区间所以必须设置最低出力约束。这不像电池那样可以从0开始平滑调节在建模时需要用二进制变量来表征要么不运行要么运行在某个以上的功率区间。第三库容约束和电池的SOC上下限类似但还需要考虑生态流量、防洪等附加约束。废弃矿井场景下相对简单一些主要就是上水库不能溢出、下水库不能被抽干。我在代码里额外加了功率平衡约束的松弛变量——当所有电源出力加起来仍不能满足负荷时用失负荷量来补充当出力超过负荷且储能都满了时用弃风弃光量来平衡。这两个松弛变量会进入目标函数并受到惩罚这样优化算法就会尽可能减少失负荷和弃电而不是直接把约束放宽了事。3. 调度优化目标函数与求解方案模型建完之后接下来是优化问题的数学表达。从计算角度看这是一个混合整数线性规划问题——连续变量负责功率和电量的分配二进制变量负责启停状态和充放电互斥性的判断。选择MILP的核心原因是求解器成熟、全局最优性有保证而且主流的能源调度研究都认可这个框架。3.1 目标函数的建立目标函数的标准写法是运行总成本最小化。我在实际项目中把成本拆成了以下几项向电网购电的成本如果系统可以和外网交换功率电池和抽水蓄能的运维成本按充放电量计费弃风弃光的惩罚成本失负荷的惩罚成本电池寿命损耗的折算成本把各项写进目标函数之后可以总结为如下形式我用LaTeX风格的伪代码描述方便你对照自己的实现min sum_t [ c_buy * P_grid_buy(t) * dt c_om_b * (P_ch(t) P_dis(t)) * dt c_om_p * (P_pump(t) P_gen(t)) * dt c_cur * (curt_w(t) curt_pv(t)) * dt c_loss * P_loss_load(t) * dt ]这里有几个值得注意的设计细节。弃风弃光惩罚系数一般要设置得比购电成本高否则优化算法会倾向于随便弃掉新能源然后去购电这就失去了优先消纳的意义。失负荷惩罚系数则要设置成所有系数里最高的体现出保供电的优先级。如果你更关心新能源消纳率可以把目标函数调整成优先最大化风光的实际消纳量并通过约束条件保证购电成本不超过某一上限。这种切换在Yalmip中只需要改几行所以建议前期把两种情况都搭建出来分析结果时可以互相验证。3.2 约束条件的数学表达约束条件按类别可以分为平衡约束、设备约束、时序耦合约束三类我逐个说清楚。功率平衡约束是最核心的等式约束风电出力 光伏出力 电池放电功率 - 电池充电功率 抽水蓄能发电功率 - 抽水蓄能抽水功率 外网购电功率 负荷功率注意在等式左侧补充弃风弃光量和失负荷量作为松弛项这样约束在数学上才是恒可行的——你不会因为一个时段数据极端导致整个模型无解。设备约束主要是上下限约束和启停逻辑约束。对电池来说同一时刻不能同时充放电用二进制变量b_bat来区分P_ch(t) P_ch_max * b_bat(t) P_dis(t) P_dis_max * (1 - b_bat(t))对抽水蓄能来说除了类似的互斥判断还要加上最小技术出力约束。我补充说明为什么互斥约束必须用二进制变量——连续变量的线性规划中没有b_bat这种整数变量的话充放电功率可能同时为正且互相抵消白浪费能量。时序耦合约束是储能设备的核心SOC和库容的动态递推必须严格写进去同时保证周期首尾状态一致或满足设定的初始条件。常见的做法是设定初始SOC等于终态SOC这样调度结果可以无限周期循环下去不会因为第一天开始的电量从哪来这个问题产生矛盾。3.3 求解策略与Matlab实现方案选择Matlab下求解这个问题的方案有三个层次我按推荐程度排序方案工具适用场景缺点Yalmip Gurobi/Cplex外部商用求解器中大规模问题、研究级需求需要额外安装并申请licenseYalmip intlinprogMatlab自带中小规模问题、学习起步大规模时求解速度较慢纯Matlab手写矩阵建模自带优化工具箱熟悉编程、小规模验证建模工作量大容易出错我用的是第一种方案。Yalmip是一个建模层工具它的核心优势是把数学约束翻译成求解器能吃的标准形式让建模和求解彻底分离。你不需要手写约束矩阵只需要像写数学表达式一样写约束条件非常直观也不容易出错。有一点要提前提醒Gurobi和Cplex对学生和科研用户都有免费license但申请流程不同Gurobi需要绑MAC地址Cplex的社区版本有规模限制。如果你的模型规模不大直接用Matlab自带的intlinprog也可以跑只是碰到整数变量多的时候可能要等比较久。4. 实操环节Matlab代码实现与关键步骤前面的模型和数学规划都理清楚了这部分是实际把代码跑起来的过程。我从数据准备、模型编写、求解与后处理三个阶段来说明。这些代码都是基于常见实践整理的通用框架你可以直接对照自己的项目做替换。4.1 数据准备与场景生成调度的基础是输入数据负荷曲线、风电出力、光伏出力、储能参数等。数据来源可以是实测数据、公开数据集或者仿真生成数据。在实际项目里我遇到的常见情况是实测数据不完整或分辨率不匹配这时候需要进行数据清洗和插值处理。风力发电时间序列的生成常见做法是用风速数据配合风机功率曲线来算。Matlab里实现风速到功率的转换非常高效% 风速序列 - 风电出力序列 v_cut_in 3; % 切入风速 m/s v_rated 12; % 额定风速 m/s v_cut_out 25; % 切出风速 m/s P_rated 100; % 额定功率 MW wind_speed [一系列风速数据]; % 时序数据长度与调度周期一致 P_wind zeros(size(wind_speed)); P_wind(wind_speed v_cut_in wind_speed v_rated) ... P_rated * (wind_speed(wind_speed v_cut_in wind_speed v_rated).^3 - v_cut_in^3) / (v_rated^3 - v_cut_in^3); P_wind(wind_speed v_rated wind_speed v_cut_out) P_rated;注意这段代码用逻辑索引一次性完成所有时段的风速转换不需要写for循环在数据长度很长时效率差距非常明显。光伏出力序列的生成需要考虑辐照度的日变化特征。如果手上没有真实的辐照度数据可以使用经典的日辐照度模型进行近似然后转换成出力% 光伏出力简化模型基于辐照度 G_stc 1000; % 标准测试条件下的辐照度 W/m^2 P_pv_rated 80; % 光伏额定功率 MW irradiance [辐照度时序数据 W/m^2]; P_pv P_pv_rated * (irradiance / G_stc); P_pv(P_pv 0) 0; P_pv(P_pv P_pv_rated) P_pv_rated;数据准备好之后用Matlab的timeseries或简单数组存储即可。我强烈建议在建模前先画一下数据曲线确认风光出力走势和负荷曲线是否对得上、是否有明显异常值。如果输入数据有严重错误后面所有结果都是白算。4.2 模型编写与求解这一部分我用Yalmip来实现。先定义决策变量再写约束和目标函数。核心代码的骨架如下%% 调度周期设置 T 24; % 24个时段如果步长为1小时 dt 1; % 时间步长 小时 %% 参数初始化 P_load [负荷时序数据长度T]; P_wind_pred [风电预测出力时序数据长度T]; P_pv_pred [光伏预测出力时序数据长度T]; E_bat_rated 200; % 电池额定容量 MWh P_bat_max 50; % 电池最大充放电功率 MW eta_ch 0.95; % 充电效率 eta_dis 0.95; % 放电效率 SOC_init 0.5; % 初始SOC SOC_max 0.9; SOC_min 0.1; V_res_rated 100; % 抽水蓄能上库有效库容 万m^3或其他单位 P_pump_max 30; % 抽水最大功率 MW P_gen_max 25; % 发电最大功率 MW P_gen_min 5; % 最小技术出力 MW eta_p 0.85; % 抽水效率 eta_g 0.9; % 发电效率 V_init_ratio 0.5; % 初始库容比例 V_max_ratio 0.95; V_min_ratio 0.05; %% 决策变量定义sdpvar定义连续变量binvar定义二进制变量 P_bat_ch sdpvar(1, T); % 电池充电功率 P_bat_dis sdpvar(1, T); % 电池放电功率 SOC sdpvar(1, T); % 电池SOC P_pump sdpvar(1, T); % 抽水蓄能抽水功率 P_gen sdpvar(1, T); % 抽水蓄能发电功率 V_res sdpvar(1, T); % 上水库蓄水量 P_grid sdpvar(1, T); % 外购电功率 curt_wind sdpvar(1, T); % 弃风功率 curt_pv sdpvar(1, T); % 弃光功率 loss_load sdpvar(1, T); % 失负荷功率 u_bat binvar(1, T); % 电池充放电状态1充电0放电 u_pump binvar(1, T); % 抽水状态1抽水 u_gen binvar(1, T); % 发电状态1发电 %% 约束条件 Constraints []; % 功率平衡约束 Constraints [Constraints, P_wind_pred - curt_wind P_pv_pred - curt_pv ... P_bat_dis - P_bat_ch P_gen - P_pump P_grid loss_load P_load]; % 电池SOC动态 Constraints [Constraints, SOC(1) SOC_init]; for t 1:T-1 Constraints [Constraints, SOC(t1) SOC(t) eta_ch*P_bat_ch(t)*dt/E_bat_rated - P_bat_dis(t)*dt/(eta_dis*E_bat_rated)]; end % 周期SOC一致性可选 % Constraints [Constraints, SOC(T) SOC_init]; % 电池功率与SOC限值 Constraints [Constraints, 0 P_bat_ch P_bat_max]; Constraints [Constraints, 0 P_bat_dis P_bat_max]; Constraints [Constraints, SOC_min SOC SOC_max]; % 电池充放电互斥 Constraints [Constraints, P_bat_ch P_bat_max * u_bat]; Constraints [Constraints, P_bat_dis P_bat_max * (1 - u_bat)]; % 抽水蓄能库容动态 Constraints [Constraints, V_res(1) V_init_ratio * V_res_rated]; for t 1:T-1 Constraints [Constraints, V_res(t1) V_res(t) eta_p*P_pump(t)*dt - P_gen(t)*dt/eta_g]; end % 抽水蓄能库容限值 Constraints [Constraints, V_min_ratio*V_res_rated V_res V_max_ratio*V_res_rated]; % 抽水功率约束与状态耦合 Constraints [Constraints, 0 P_pump P_pump_max]; Constraints [Constraints, P_pump P_pump_max * u_pump]; % 发电功率约束与状态耦合含最小技术出力 Constraints [Constraints, P_gen_min * u_gen P_gen P_gen_max * u_gen]; % 抽水和发电互斥 Constraints [Constraints, u_pump u_gen 1]; % 弃风弃光、失负荷非负 Constraints [Constraints, 0 curt_wind P_wind_pred]; Constraints [Constraints, 0 curt_pv P_pv_pred]; Constraints [Constraints, loss_load 0]; %% 目标函数 c_grid 0.5; % 购电电价 元/kWh注意单位统一 c_om_bat 0.02; % 电池运维成本 元/kWh c_om_pump 0.01; % 抽蓄运维成本 元/kWh c_cur 2.0; % 弃风弃光惩罚系数 c_loss 10; % 失负荷惩罚系数 Objective sum(c_grid * P_grid * dt c_om_bat*(P_bat_ch P_bat_dis)*dt ... c_om_pump*(P_pump P_gen)*dt c_cur*(curt_wind curt_pv)*dt ... c_loss * loss_load * dt); %% 求解 ops sdpsettings(solver, gurobi, verbose, 2); optimize(Constraints, Objective, ops); %% 提取结果 P_bat_ch_opt value(P_bat_ch); P_bat_dis_opt value(P_bat_dis); SOC_opt value(SOC); P_pump_opt value(P_pump); P_gen_opt value(P_gen); V_res_opt value(V_res); P_grid_opt value(P_grid);这段代码在真实项目中是可以直接跑通的骨架。有几个细节我要再强调一遍功率平衡约束里的单位必须全局统一。比如负荷单位是MW储能功率单位是MW那么库容公式里的dt * P对应的电量单位就是MWh。如果你的库容用万立方米来计量还需要引入单位换算系数否则约束的量纲对不上结果会很奇怪。还有一个常见问题是初始SOC和终态SOC的设定。如果你只设置初始值而不约束终值优化算法会在最后一个时段把SOC用尽或者充满因为只在单周期内优化时剩余电量不会带来收益。解决办法是加SOC(T) SOC_init或者给终态电量一个价值系数。我在上面代码里用注释标注了可选项实际项目中建议加上这样调度结果才具有现实的周期性参考意义。4.3 结果可视化与灵敏度分析求解完成之后可视化这一步不能省。我通常至少画三张图第一张是功率平衡堆叠图用stacked bar或者area图展示每个时段各类电源的出力构成直观反映风电、光伏、电池、抽蓄在一天内如何协同满足负荷。这张图也是论文里最常使用的结果图。第二张是储能调度曲线图把电池SOC、抽蓄库容、充放电功率画在一张图里看变化趋势。如果SOC曲线出现剧烈的锯齿形波动说明时间常数设置不合理或者惩罚系数有问题。第三张是弃风弃光与失负荷图用于检查系统是否存在严重的供需失衡。如果失负荷在多个时段持续出现可能是储能容量配置不够或者光伏装机比例过高可以通过调整参数做灵敏度分析验证。灵敏度分析建议优先做以下几组电池额定容量变化对弃光率和运行成本的影响抽水蓄能容量变化对系统削峰效果的影响负荷曲线偏移比如夏季空调负荷升高对调度策略的影响这些分析能直接回答电池和抽蓄的容量配比到底怎么选这个工程问题比单纯的美化调度图更有价值。5. 常见问题与排查技巧实录代码跑不通、结果不合理、求解时间过长这三个问题几乎每个做调度优化的人都会遇到。我把实际项目里踩过的坑和排查思路整理成一个速查表方便你对照。5.1 求解器选择与配置问题如果你用的是Yalmip Gurobi方案最常见的报错是找不到求解器或者license无效。Yalmip的sdpsettings(solver, gurobi)需要Gurobi正确安装并添加到MATLAB路径。我建议用yalmiptest命令测试一下安装是否成功它会自动检测所有已安装的求解器并显示状态。如果没有商业求解器退一步用intlinprog也是可行的。在Yalmip中只需要把solver设置改成intlinprog即可模型代码不需要改动。但要注意intlinprog在大规模整数规划上的性能明显弱于Gurobi我在一个含48个时段、6个二进制变量的模型上测试过Gurobi大概2秒求解intlinprog要跑20多秒再往大了差距会更明显。5.2 数值稳定性与SOC漂移问题SOC漂移是电池储能调度中最隐蔽的问题。现象是长时间运行模拟时SOC的均值缓慢上升或下降一段时间后偏离真实物理范围。原因通常有两个第一单周期的初始SOC和终态SOC没有闭环约束导致每个周期结束时残留电量不断累积。解决方法是加上等式约束或者给终态电量赋予价值。第二充放电效率的数值太极端。比如充电效率0.99、放电效率0.99看起来很高但一天两次循环下来能量损耗仍然是可观的。如果效率取1相当于储能变成了无损的能量仓库优化结果也会失真。我一般取0.9~0.95之间的值并检查一个完整循环后的SOC是否合理。还有一个数值问题来自大数与小数的混合。目标函数中购电成本可能到几百万元级别而运维成本可能只有几块钱两者差距悬殊时低权重项在优化中几乎不起作用。我建议对所有成本系数做归一化处理或将目标函数拆成多个量级相近的部分不要让数值差距超过10的6次方。5.3 模型复杂度控制策略当T从24扩展到168一周甚至8760一年时模型规模直线上升。这时求解时间可能从几秒膨胀到几十分钟。我的经验是优先做三类简化时段聚合用电负荷和风光出力曲线进行分段代表性的聚合比如把一天分成6个典型时段用加权平均出力代表每个时段代价是失去了小时级的细节但趋势判断完全够用。这个技巧在对全年数据进行概算时尤其有效。线性化近似把抽水蓄能的非线性效率曲线用分段线性函数逼近。实际测试中三段线性逼近的精度就能达到可接受的水平。滚动优化把完整周期切成若干重叠窗口逐个求解并传递状态量作为下一个窗口的初始条件。这样做牺牲了全局最优性换来了计算速度的大幅提升。实际工程中滚动优化更贴近预测-控制-更新的真实运行逻辑。5.4 结果不合理时的排查方向如果你得到的结果里出现电池在光伏低谷期放电、在光伏高峰期充电这种反直觉现象先别急着怀疑求解器。按这个顺序排查数据有没有写反——负荷时序和光伏出力时序的排列方向是否一致有没有把头尾接错符号有没有搞错——功率平衡等式里充放电项的符号方向我见过有人把电池放电写成减号结果越放电负荷缺得越多单位有没有统一——MW/MWh/元之间的换算最容易出错的地方是dt和成本系数的单位约束有没有写全——比如漏了电池SOC的上下限约束结果SOC可能跑到负值去如果以上都检查过了结果还是不对试着把储能容量设成极大值跑一遍看看系统是否趋向于全部电量靠储能搬运的极端解如果极端解合理说明约束本身没错是参数比例问题。6. 项目扩展与后续研究方向这个项目的框架搭好之后能扩展的方向非常多。我列几个我认为最有实际价值的供正在找切入点的同行参考。6.1 不确定性建模从确定性调度到鲁棒/随机调度目前的模型用风电、光伏的预测值作为输入属于确定性优化。实际运行中预测误差无法忽略——我见过风电预测误差达到30%以上的极端天气。下一步可以在模型中加入不确定集合把风电光伏出力表示成一个区间或一个场景集用鲁棒优化或两阶段随机规划来求解。这个方向在学术上属于热点工程上的收益也很实在。两阶段随机规划的标准思路是第一阶段决定储能的充放电计划第二阶段根据风光实际出力调整机组出力。Yalmip对这类问题的支持也很友好可以把现有模型直接扩展。6.2 多目标与碳排放约束如果项目需要考虑低碳运行可以在目标函数中加入碳排放成本或者把新能源渗透率作为一个硬约束。这样调度算法会在经济性和低碳性之间自动折中。我的一点体会是碳约束的加入会显著提高储能的调度频次——因为火电作为备用电源被限制使用后储能需要承担更多调节任务。6.3 多矿区联合调度与电网互动如果考虑的不是单个废弃矿井而是一个矿区群的多个抽蓄站点联合调度问题会变成一个多站点时空协调问题。这时候矩阵化的Matlab建模优势就体现出来了你可以用多维数组来表示站点、时段、状态变量三维结构配合向量化运算求解。更进一步如果把这个微网/局域电网接入主网加入与主网的功率交换协议和需求响应机制模型会变得复杂很多但应用价值也随之上升。这类研究需要较多的电力市场知识建议先从简单的分时电价机制入手再逐步扩展。写在最后这个项目做下来我的体会是风光储互补调度的难点从来不在某个单独的数学模型上而在于能不能把物理过程准确地翻译成数学语言再用合适的工具求解出来。Matlab加Yalmip这条技术路线从建模效率、求解能力到结果可视化确实是目前最适合研究验证的组合。再分享一个小技巧。做完基本调度之后试着把储能参数电池容量、抽蓄容量故意调成几个极端值看看系统的运行成本和新能源利用率如何变化你会对自己的模型特性有非常直观的理解。这种故意犯错式的灵敏度分析往往比正常参数扫描更能帮你发现建模的隐患。如果你的项目也涉及类似的混合储能互补调度建议从最简单的两设备模型开始跑通再逐步加入更多约束和不确定性分析。模型每多一层结果的可解释性就需要重新审视。祝顺利。

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价 →
↑