ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

基于Matlab+Yalmip的共享储能电站日前优化经济调度建模与实现

基于Matlab+Yalmip的共享储能电站日前优化经济调度建模与实现 简介共享储能电站的用户日前优化经济调度Matlab源码面向电力系统、储能技术研究方向的在校生与工程师用于解决未来电价与负荷预测条件下储能系统最优充放电计划的制定问题。资源压缩包共2个文件均为.m脚本包体仅4KB分别实现两个案例脚本前者侧重基础场景建模后者引入更复杂的不确定性和优化策略。已有401人学习下载。代码中涉及电池充放电效率、容量与功率约束、电价与负荷预测处理以及动态规划、遗传算法或粒子群等优化方法的调用可帮助读者理清日前调度问题的建模脉络和求解流程。运行后还可以分析总成本、节约电费与电池使用情况验证策略有效性适合作为课程设计、毕业设计或科研入门参考。1. 共享储能电站的用户日前优化经济调度到底在算什么共享储能电站的日前优化经济调度解决的是用户侧“明天 24 小时怎么充放电”这一个问题。输入只有三样东西用户负荷预测曲线、分时电价表、储能系统的容量与功率参数。输出是一组充电/放电曲线以及一天下来用户要向电网支付的总电费。Matlab 在这个问题上的主要价值不是算得快而是模型能快速改换一条负荷曲线、改两行约束再跑一遍就能得到新的调度方案。很多刚接触这个方向的人会把重点放在“储能”上反复调电池参数最后发现调度曲线还是不对。真正决定调度形状的是用户负荷与分时电价的叠加关系电价低谷时段负荷低充电有空间电价高峰时段负荷高放电能抵掉最贵的电。共享储能电站的特殊之处在于电池不是某一家独占而是多个用户按容量份额共用于是还要解决一个“谁在什么时段用多少功率”的分配问题。这篇文章按建模型、写代码、整定参数、处理多用户分配、回测验证五个步骤展开。读者可以是做用户侧储能方案设计的工程师也可以是电力系统方向的研究生。全程用 Matlab 编码模型是典型 MILP 结构代码可以直接改参数跑通。2. 建模从目标函数起步共享储能电站日前调度怎么把成本写进去2.1 决策变量只取三个模型结构就稳了日前调度的时间分辨率通常取 1 小时一天划分成 24 个时段也可以取 15 分钟96 点让曲线更平滑。无论哪种分辨率决策变量都只有三类充电功率、放电功率、荷电状态。负荷和电价是已知输入电池容量和功率限制是常量都不应该出现在决策变量里。以一小时模型为例常见变量表如下变量含义单位典型取值范围P_ch(t)t 时段充电功率kW0 到 PCS 额定功率P_dis(t)t 时段放电功率kW0 到 PCS 额定功率e_soc(t)t 时段末电池剩余能量kWh10% 到 90% 额定容量z(t)充放电互斥标志0/11 表示充电0 表示放电这里建议把荷电状态直接用能量单位 kWh 表示而不是百分比。很多源码里用百分比 SOC在递推公式里还要再乘一次容量量纲容易混。写成 kWh 之后SOC 递推公式天然就是能量的加加减减最后画图时除以容量转回百分比即可。共享储能电站和单用户自建储能的建模差异主要在功率和容量约束上。单用户模型只有一个 P_ch(t) 和 P_dis(t)而共享电站需要给每个用户单独建一组变量再叠加全站的总功率约束。第一部分先按单用户建模多用户分配放到后面单独处理。2.2 目标函数由三段组成购电成本、折旧成本和循环损耗目标函数的目标是让用户一天的总成本最小。用户从电网净购电功率等于负荷功率加上充电功率再减去放电功率乘以该时段电价并求和就是基础电费项。目标函数可以写成min Σ price(t)·(P_load(t) P_ch(t) − P_dis(t)) dep·(P_ch(t) P_dis(t)) / 2第一项是分时电价下的购电成本充电时净购电增加放电时净购电减少。第二项是电池折旧成本dep 表示每完成一个完整充放电循环损耗折算到每 kWh 的成本。之所以除以 2是因为一次完整循环里充电和放电各计一次若直接乘 (P_ch P_dis)相当于同一度电被计了两次折旧。折旧项必须有。如果不加只要峰谷价差为正优化器就会让电池一直满充满放哪怕充放效率损耗已经吃掉大部分收益。实际工程中如果锂电池循环寿命约 6000 次且电池更换成本按 0.5 元/Wh 计算折算下来每循环一度电的折旧成本大约在 0.05 到 0.15 元之间。当日价差低于这个值电池在低谷充电、高峰放电就不再有经济价值。部分源码还会加一个峰谷套利收益项本质和购电成本项等价只是换了符号。建议统一用购电成本形式因为“成本最小化”更符合用户侧电费结算逻辑也方便后期叠加需量电费或需求响应惩罚项。2.3 四条硬约束逐个确认功率、递推、互斥、SOC端点约束条件不写全优化结果就是废的。第一个约束是功率上下限充电功率不能超过 PCS 额定功率放电功率同理。第二个约束是 SOC 递推关系相邻时段电池能量满足e_soc(t1) e_soc(t) η_ch·P_ch(t) − P_dis(t)/η_dis其中 η_ch 和 η_dis 分别是充电和放电效率。第三个约束是充放电互斥不能同一时刻既充电又放电。这个约束必须显式写否则电池会出现“充电给放电供电”的循环既不物理也不经济。处理办法是用一个二元变量 z(t)充电时 z(t)1放电时 z(t)0P_ch(t) ≤ P_max·z(t) P_dis(t) ≤ P_max·(1−z(t))第四个约束是 SOC 边界和日末约束。e_soc(t) 要落在容量上下限之间日末 e_soc(24) 一般要求等于日初值。这个“回起点”约束很关键它保证优化结果是可持续执行的如果今天把电池放空明天就没有可调度资源了。有些工程场景允许日末 SOC 在某个区间内浮动比如 0.4 到 0.6这时要配合月度累计约束一起用。提示还有一种常见写法是把互斥约束改成大 M 方法用 M·z(t) 松弛功率上限。M 取值过大会造成数值问题建议直接用二元变量形式求解器处理更稳定。3. Matlab源码骨架用Yalmip把日前经济调度跑成可复现的优化结果3.1 求解器选型为什么不用手写单纯形法这个优化问题属于混合整数线性规划因为存在二元变量 z(t)。规模增大后比如 96 时段、10 个用户单纯手写线性规划算法没有意义。常见做法是用 Yalmip 建模替换调用 Gurobi 或 Cplex 求解。Yalmip 是 Matlab 环境下的建模语言支持用 sdpvar 声明变量、用约束拼接的方式描述模型并自动完成求解器适配。Matlab 自带的优化工具箱也能解 MILP但有两个不便一是 intlinprog 的输入是矩阵形式建模时要把约束逐个展开成系数矩阵代码很难维护二是换求解器要重写接口。Yalmip 把变量声明和约束描述与求解器解耦换求解器只需要改 sdpsettings 里的一行。这也是目前共享储能调度类完整源码里用得最多的结构。3.2 一份可直接运行的调度源码Yalmip 最小可跑版本%% 共享储能电站日前优化经济调度 - Matlab/Yalmip 最小实现 clear; clc; % ---------- 基本参数按实际工程替换 ---------- T 24; % 调度时段数1 小时一个点 price [0.35 0.35 0.35 0.35 0.35 0.35 0.35 1.10 ... 1.10 1.10 1.10 0.65 0.65 0.65 0.65 0.65 ... 1.10 1.10 1.10 1.10 0.65 0.65 0.65 0.65]; P_load [120 110 105 100 95 90 130 220 260 250 180 ... 160 150 160 180 200 230 240 220 180 150 ... 140 130 120]; % 用户日前负荷预测kW E_cap 500; % 储能容量kWh P_max 120; % PCS 最大充放电功率kW eta_ch 0.95; % 充电效率 eta_dis 0.92; % 放电效率 SOC_min 0.1; % 荷电状态下限比例 SOC_max 0.9; % 荷电状态上限比例 SOC0 0.5; % 日初 SOC dep 0.08; % 电池单次完整循环折旧成本元/kWh % ---------- 声明决策变量 ---------- p_ch sdpvar(T,1); % 充电功率 p_dis sdpvar(T,1); % 放电功率 z binvar(T,1); % 0/1 互斥变量 e_soc sdpvar(T1,1); % 各时段末电池能量kWh % ---------- 约束条件 ---------- Cons []; Cons [Cons, p_ch 0, p_ch P_max * z]; Cons [Cons, p_dis 0, p_dis P_max * (1-z)]; Cons [Cons, e_soc SOC_min * E_cap, e_soc SOC_max * E_cap]; Cons [Cons, e_soc(1) SOC0 * E_cap]; for t 1:T Cons [Cons, e_soc(t1) e_soc(t) ... eta_ch * p_ch(t) - p_dis(t) / eta_dis]; end Cons [Cons, e_soc(T1) SOC0 * E_cap]; % 日末 SOC 回到初始值 % ---------- 目标函数 ---------- Obj sum(price .* (P_load p_ch - p_dis)) ... 0.5 * dep * sum(p_ch p_dis); % ---------- 求解 ---------- Ops sdpsettings(solver,gurobi,verbose,0); Result optimize(Cons, Obj, Ops); % ---------- 结果提取 ---------- if Result.problem 0 P_ch_opt value(p_ch); P_dis_opt value(p_dis); E_soc_opt value(e_soc(2:T1)); disp(优化成功); else disp(求解失败请检查约束是否冲突或求解器是否安装); end3.3 代码执行逻辑与参数对照这段代码的核心逻辑分四步。第一步用 sdpvar 声明变量p_ch 和 p_dis 是连续变量z 是二进制变量e_soc 是 T1 维连续变量多出来的一个点留给日末状态。第二步通过 [] 拼接约束Matlab 里 Yalmip 用方括号把约束条件聚合成一个约束集最后传给 optimize。第三步是 SOC 递推。循环从 1 到 Tt 时刻充电会增加电池能量放电会减少效率分别处理在充放电两侧。这里全部用 kWh 计算没出现百分比避免量纲混乱。第四步写目标函数前一项是购电成本后一项是折旧成本。要特别注意 price 与 (P_load p_ch - p_dis) 是按元素相乘Matlab 里必须用点乘 .*符号写错会直接报错。提示如果你的环境没有 Gurobi可以把 solver 改成 cplex 或 linprog。注意 linprog 不支持二元变量必须用 intlinprog而 Yalmip 会在 optimize 时自动帮你匹配。4. 用户侧参数整定分时电价与储能容量如何决定调度曲线4.1 峰谷价差小于折旧成本时储能不动作是正确结果很多初学者跑完源码发现电池完全不充放第一反应是代码写错了。实际上这很可能是正确结果如果峰谷价差扣掉充放损耗和折旧成本之后没有利润最优策略就是不用电池。在给定价格结构下优化器会自己判断“这度电倒一手划不划算”。具体阈值可以这样估算低谷充电 1 kWh按 0.95 效率并最终放电 0.95 kWh放电收益要覆盖充电成本加上折旧。假设谷电 0.35 元/kWh折旧 0.08 元/kWh则放电电价至少要高于 0.35/0.95 0.08/0.95 ≈ 0.45 元储能才有动作空间。峰谷价差调度曲线特征工程结论小于 0.15 元全天 SOC 保持初始值几乎不动作储能套利无利润空间0.2 到 0.4 元每天 1 次充电 1 次放电SOC 曲线单峰基本套利模式曲线较稳定大于 0.6 元可能出现早晚各一次放电SOC 双峰需重点检查 P_max 是否限制放电出力这个表可以作为参数整定的第一道判断工具。如果价差不小但电池仍不动作再查折旧项是不是设得过高或者充放效率设置太低。4.2 储能容量从 200 到 800 kWh 的灵敏度扫描容量参数直接决定 SOC 曲线的形状和最大可转移电量。工程上通常用循环扫描的方式确认容量选型在 Matlab 里把上面的主程序包成函数外层循环改 E_cap每次记录目标函数值和最大放电深度。cap_list 200:100:800; cost_list zeros(size(cap_list)); for k 1:length(cap_list) E_cap cap_list(k); run_shared_storage_model; % 复用主程序E_cap 在模型内部参与计算 cost_list(k) value(Obj); end plot(cap_list, cost_list / 1000, o-); xlabel(储能容量/kWh); ylabel(日购电成本/千元);扫描结果通常呈 L 形下降曲线容量从 200 加到 500成本明显下降超过 500 后边际收益快速递减。原因是 P_max 只有 120 kW就算容量再大一天能转移的电量也被功率上限卡住了。在场站选型时如果容量继续增加但成本不再降说明瓶颈已经转移到 PCS 功率下一步应该提高 P_max。4.3 不设 SOC 终值约束调度曲线会有多离谱把第 3 章代码里的 e_soc(T1) SOC0 * E_cap 这行删掉再跑一次会看到 SOC 曲线结束时被压在 0.1 的边界上。原因是优化器为了节省购电成本会在最后一个高峰时段把电池全部放光至于明天还有没有电可用它不管。这就是单日调度模型最容易踩的坑。SOC 终值约束不只是技术细节它决定了调度方案是否可持续。实际操作中如果要求日末回到 0.5而当天负荷波动大导致无法回点求解器会返回不可行。这时把等号约束放宽成区间约束比如 e_soc(T1) 0.4·E_cap 且 e_soc(T1) 0.6·E_cap并用一个罚函数控制偏离模型也不会至于死锁。5. 多用户共享储能的分配机制权重、公平性与迭代修正5.1 单用户最优不是全局最优总功率约束必须显式建模如果是多个用户共享一个储能电站先把每个用户单独优化再拼起来结果往往不可执行。原因在于共享电站的 PCS 功率上限和容量上限是全站统一的单独优化没有把“同一时刻站内总充放功率不超过上限”这个约束放进去。正确建模方法是给每个用户分别建立决策变量 p_ch_i(t)、p_dis_i(t) 和 e_soc_i(t)然后叠加全站约束Σ p_ch_i(t) ≤ P_station_ch_maxΣ p_dis_i(t) ≤ P_station_dis_max。容量分配则通过每个用户的 E_cap_i 体现各用户 SOC 独立递推。第一个问题随之而来全站功率上限如何分配给用户。最简单是等比例分配即每个用户固定获得 1/N 的功率额度和容量额度。等比例的问题在于用户的负荷曲线差异很大白天空调的负荷峰值在下午而生产线负荷在上午等比例分配会浪费一部分放电通道。5.2 比例削减迭代修正的 Matlab 实现一种快速修正方法是“先各自优化再按比例削减越限功率”。每一步判断全站总功率是否超限超限则按该用户当前功率占总额的比例缩减。代码结构如下% 多用户共享储能电站的迭代修正分配 P_shared 300; % 全站充电功率上限kW N_user 3; p_ch_all zeros(N_user, 24); p_dis_all zeros(N_user, 24); % 第一步各用户独立求解并填入 p_ch_all for i 1:N_user [p_ch_all(i,:), p_dis_all(i,:)] solve_single_user(i); end % 第二步逐时段检查总充电功率并比例削减 for t 1:24 total_ch sum(p_ch_all(:, t)); if total_ch P_shared ratio P_shared / total_ch; p_ch_all(:, t) p_ch_all(:, t) * ratio; end end这段代码的核心是逐时段扫描而不是对整个调度周期做统一缩放。因为每个时段的越限情况不同统一乘系数会把本来合规的时段也无谓削减导致储能利用率下降。逐时段处理之后受影响的只是超标时段其他时段不受牵连。比例削减的缺点在于削减后用户的 SOC 递推关系被打破了充电功率变小日末 SOC 可能回不到目标值。所以实际工程做法有两种一是削减后重新求解一次完整优化模型把削减后的功率作为上限约束二是直接在全局模型中写共享功率约束由求解器一次性处理。第二种方法效果最好但变量规模会随用户数量线性增长10 个用户 96 时段大约 3000 个变量和约束Gurobi 仍然能秒级求解。5.3 公平性扩展纳什讨价还价作为加权目标当各用户为同一个共享储能电站分担投资成本时单纯按功率比例分配会被认为不公平。例如夜间充电时段A 用户负荷小需要更多充电功率来蓄能B 用户夜间也有一定负荷充电空间有限。等比例分配会让 A 用户吃亏。常见的进阶方案是把分配问题变成收益分配问题。先算出各用户单独不配置储能的原始电费 C_i_original再优化共享储能下的总成本 C_total目标是让每个用户的分摊成本都尽量小。纳什讨价还价模型写成最大化 Σ ln(C_i_original − C_i_share) 的形式。这一项在 Yalmip 里不容易直接线性化工程常用做法是把目标函数改成加权求和权重根据各用户历史用电量或投资比例设定。这样模型仍是线性规划求解速度和稳定性不受影响。用户数不大时也可以在外部循环调整权重用多层迭代逼近纳什解。6. 回测验证历史负荷数据下怎么确认这套调度方案真的省钱6.1 回测前先定好三个对照方案共享储能调度是否真的经济不能只看优化后的购电成本数值必须和基准方案对比。建议至少跑三组不装储能、单用户自建同等容量储能、共享储能。三组模型用同一套负荷历史数据起止日期一致电价表一致结果才有可比性。对比表至少包含日均购电成本、高峰时段购电比例、日循环次数三个指标。方案日均购电成本/元高峰时段购电比例日充放循环次数无储能直接购电286031%0单用户自配 500 kWh 储能271519%0.9共享储能同容量分配259813%1.2单用户自配储能和共享储能使用相同总容量时共享模式循环次数更高原因是用户负荷峰值时间错开电池可以在一天内被更多用户利用。这是共享储能电站经济性的核心来源但如果回测结果显示共享方案与自配方案收益接近说明用户负荷曲线高度重合共享价值有限。6.2 回测指标与最小核对代码回测不能只看平均收益还要检查约束是否在真实数据下被违反。真实负荷不等于预测负荷日前调度按预测曲线算出来的充放电计划回放时可能让 SOC 越限。最小核对代码建议用以下结构% 用真实负荷回放日前调度结果 SOC_real zeros(T1, 1); SOC_real(1) SOC0 * E_cap; for t 1:T SOC_real(t1) SOC_real(t) eta_ch * P_ch_opt(t) ... - P_dis_opt(t) / eta_dis; end violation sum(SOC_real SOC_min * E_cap) ... sum(SOC_real SOC_max * E_cap); cost_real sum(price .* (P_load_real P_ch_opt - P_dis_opt));SOC 越限次数是回测里最容易出问题的指标。如果越限次数大于 0优先调整的不是优化模型本身而是负荷预测的保守程度在预测负荷上增加安全裕度或把 SOC 限值从 0.1/0.9 收紧到 0.2/0.8。共享储能电站涉及多个用户时还要监控每个用户的独立 SOC全站平均 SOC 正常不代表某个用户没有越限。6.3 收益不达标时的排查顺序如果回测结果显示共享储能方案比无储能方案成本下降不到 3%按以下顺序排查。先看峰谷价差是否覆盖折旧成本只看 0.5 以上价差段是否有充放动作再看日末 SOC 约束是否把放电空间全部锁死把 SOC0 从 0.5 调整到 0.35观察成本变化最后检查 P_max 是不是比实际峰段负荷小太多导致放电无法抵消峰值购电。共享电站多用户场景下收益不足时还要单独打印每个用户的成本分摊看是否存在个别用户始终占用充电通道压缩了其他用户的套利空间。本文还有配套的精品资源点击获取
返回列表