资讯动态

虚拟电厂多时间尺度调度与储能衰减建模的Matlab完整复现

发布时间:2026/10/14 5:28:36 来源:尧图企业网站定制
高比例可再生能源并网之后电网调度最直观的感受就是净负荷曲线不再安静午间光伏抢火电晚峰又逼着所有机组快速爬坡。做虚拟电厂调度的人几乎天天在同一个问题上反复权衡要么多备灵活性成本高得离谱要么省储能电费结果弃风弃光、失负荷双双上来。要平衡这两个目标只能靠跨时间尺度的协调调度并把储能衰减成本真正放进优化模型里。这篇文章围绕我复现某篇顶级SCI研究中“虚拟电厂多时间尺度调度与衰减建模Matlab代码实现”的完整过程展开分享模型的构建逻辑、衰减建模方法、代码实现中的坑以及最后能直接套用的复现方法论。无论你是刚开始做虚拟电厂方向的研究生还是已经接触过机组组合、想补足储能调度经验的同学这篇都能帮你少走一大截弯路。1. 灵活性缺口到底缺在哪净负荷曲线的“脾气”说了算1.1 净负荷曲线这个隐形约束比设备本身更难对付传统的调度问题很简单负荷曲线基本可预测变化平缓机组只需要盯着最大值选容量。但高比例可再生能源并网后真正决定调度难度的是一条间接曲线——净负荷也就是原始负荷减去风光出力的差值。光伏午间出力冲高风电场凌晨发力这些波动叠加在负荷曲线上让净负荷出现深谷、陡峰和快速爬坡。我用一个简化算例说明某地区白天系统负荷峰值约1000 MW光伏峰值800 MW午间净负荷可能只剩约300 MW傍晚光伏出力骤降而负荷还在攀升净负荷可能在两小时内从300 MW冲回900 MW以上相当于要求系统在极短时间内提供近600 MW的向上爬坡能力。如果电网里全是按基荷设计的火电这个速度根本给不出来只能靠提前压出力留备用代价就是整个午间都在低效率状态下运行。这种反调峰特性是“灵活性缺口”的根源。单纯增加装机容量解决不了问题因为新增机组在低谷时段反而会加剧最小出力约束真正缺的是“能够快速改变出力、并且方向正确的能力”。很多研究者第一次接触这个领域时容易盯着“总装机够不够”看但实际上算例跑出来的失负荷往往不是因为能量不够而是因为某个时段爬坡速度和备用容量不够。1.2 灵活性不是“够用就行”速度、幅度、持续性是三把尺子要量化灵活性不能只说“系统有灵活性”需要拆成三个维度速度每分钟能增加或减少多少出力、幅度最大出力与最小技术出力之间的可调范围、持续性这个调节能力能维持多久。这三个维度分别对应调度中的爬坡约束、出力上下限和最小连续运行时间。资源类型爬坡速度可调幅度持续能力边际成本燃煤机组1%~3%/min20%~50%额定出力数小时以上低但深调时效率差燃气轮机5%~10%/min30%~80%额定出力小时级较高储能系统分钟级甚至秒级0~100%额定功率受容量限制无燃料成本但存在寿命损耗柔性负荷响应快取决于可削减/平移量分钟级~小时级需支付补偿这份表格想说明的是没有任何单一资源能同时满足三个维度。火电机组持续性好但速度慢深调时煤耗上升严重储能速度快、双向调节方便但容量有限频繁动作又会加速衰减柔性负荷响应快但可调空间和持续时间都受用户端限制。所以虚拟电厂的价值就在于把不同特性的资源组合起来让“快的负责救急、慢的负责兜底”而不是要求所有资源都变成全能选手。实际复现中我经常提醒自己有另一句话灵活性不够的本质是某个时间断面的组合能力不够。如果只加储能而不改变机组启停计划那么晚峰爬坡时储能很可能已经被抽干了如果只增加火电开机台数午间净负荷低谷又会让系统面临最小出力越限。所以任何调度模型都必须在时间维度上协同安排这才引出后面多时间尺度调度的必要性。2. 虚拟电厂怎么把分散闲置资源变成一台可调度机组2.1 VPP成员画像谁提供能量谁提供速度谁提供弹性虚拟电厂VPP的概念不复杂它把分布式光伏、分散式风电、储能、可控负荷、电动汽车充电桩等资源聚合起来对外像一个发电厂一样参与调度和交易对内则按照各成员的物理特性和成本进行优化分配。打个粗糙的比方VPP像拼车平台单个私家车接不了机场大单但平台把几十辆顺路的车组织起来就能统一接单、按座位分配。在调度建模时我给每个成员标定了一个“性格标签”。风电和光伏是“被动型选手”出力曲线由预测决定优化中只能决定是否弃用以及弃用多少储能是“速度型选手”能够在分钟级完成双向调节但每次动作都有衰减成本柔性负荷是“弹性型选手”它们可以把峰值时段的用电平移到低谷相当于给系统提供了负向备用微型燃气轮机或柴油发电机是“可靠型选手”启动快、出力灵活但燃料成本高。这四个角色配合起来VPP才能既保证能量平衡又保证爬坡速度。复现这类SCI论文时最容易犯的错误是把VPP当成“一个大储能加一堆新能源”。实际上VPP的核心困难在于成员之间的启动成本差异、响应速度差异和能量容量差异。同一个时段可能燃气轮机开机的经济性不如多买一点储能深度放电但储能深度放电又会带来较大的寿命损耗这种取舍必须在优化模型内部体现而不是事后人工判断。2.2 日前—日内—实时三层调度怎么层层往下收口多时间尺度调度的基本逻辑是预测精度随时间的临近逐渐提高所以调度计划也应该分阶段、滚动地去修正。日前阶段通常以1小时甚至15分钟为步长优化未来24小时基于次日预测决定机组启停、储能充放电计划、与主网的购售电计划。这一层解决的是“大方向”问题比如明天下午要不要多开一台燃气轮机、储能留多少电量应对晚峰。日内阶段每2到4小时滚动一次使用更新后的短时预测在更细的时间粒度上修正日前计划。这一层解决的是“预测偏差”问题。例如日前预测午间光伏较高实际运行中云层遮挡使光伏出力降低日内优化就会提前通知储能少放电、燃气轮机增加出力。实时阶段时间粒度拉到分钟级甚至秒级主要处理分钟级的功率波动。这时候靠重新求解优化模型往往来不及通常用储能快速响应和柔性负荷快速调节来兜底再配合类似自动发电控制AGC的频率调节机制。三层之间的关系不是孤立存在的。我复现时最看重的细节是下层优化需要把上层计划作为参考边界但不是硬约束。如果日内阶段强制要求储能SOC必须与日前计划完全一致那么预测偏差稍微大一点就会让问题无解。正确做法是给SOC留一个可偏离的范围偏离超过阈值时才产生惩罚成本。这个“软约束”设计是所有多时间尺度模型能否跑通的关键也是论文里经常一笔带过、但实战中极其影响结果的地方。灵活性和成本的权衡在每一层都有不同表现日前多预留一台机组付出的是启动成本和空闲备用成本日内频繁调整储能付出的是循环寿命损耗实时动作过猛会加速衰减并带来控制风险。所以必须把衰减成本显式建模否则调度器会形成“储能可以随意用”的错误认知导致算出来的方案在经济上完全失真。3. 储能衰减不是小数目从寿命公式到成本系数3.1 电池衰减的主要来源循环深度和动作剧烈度储能衰减问题一开始很容易被简化处理很多人只把储能当作一个带SOC上下限的“水库”忽略了每次充放都在消耗寿命。实际上电网侧储能的寿命损耗主要由两个因素驱动循环老化和日历老化。循环老化指的是电池每经历一次充放电循环正负极材料结构和电解液界面都会发生不可逆变化循环越深、次数越多容量衰减越快日历老化则是指即使电池放着不用随着时间推移容量也会缓慢下降温度越高越明显。调度优化的时间窗通常是小时级日历老化很难在短期内通过调度策略改善所以复现时重点建模循环老化。循环深度与寿命的关系非常显著一块磷酸铁锂电池如果以100%放电深度DOD循环可能只有3000次左右寿命如果只以50% DOD循环寿命能上升到近万次。这背后的物理机制是深循环时电极材料的体积膨胀收缩幅度更大活性物质颗粒容易开裂脱落副反应也更剧烈。高倍率充放电会进一步加剧这类损伤。我复现的论文里衰减建模并不到电化学机理层面而是落在工程用的半经验公式上。常见的寿命—DOD关系是一个幂函数形式N(DOD) N_ref × (DOD_ref / DOD)^kp其中N_ref是基准循环次数DOD_ref是基准放电深度kp是衰减指数一般在0.8到1.2之间。把寿命函数引入优化目标之前需要把它从“循环次数”转换成“单位吞吐量的退化成本”。3.2 从寿命曲线到单位退化成本一个能直接写进目标函数的方法假设储能容量为10 MWh系统总投资按1200元/kWh算总造价1200万元若在100% DOD下循环寿命为3000次那么全生命周期总吞吐量为3000 × 10 MWh 30000 MWh。平均到每一MWh吞吐量上的退化成本就是 1200万 ÷ 30000 400元/MWh。也就是说储能每充进去或者放出来1 MWh就应该在目标函数里计入400元的寿命损耗。这样处理后目标函数里只需要增加一项C_deg(t) λ_deg × (P_ch(t) P_dis(t)) × Δt其中λ_deg就是单位吞吐退化成本P_ch和P_dis分别是充电和放电功率Δt是时段长度。这个线性近似的好处是既保留了衰减对调度决策的约束力又不会把模型变成非线性问题MILP依然可以直接求解。需要说明的是严格来讲一个深度为100%的完整循环不等于两次50%的半循环叠加两者对寿命的损伤是不同的。用线性吞吐量近似会略微低估深循环的损伤不过对于日前和日内调度这类时间尺度它已经足够稳定。如果论文里要求更精细可以采用分段线性函数将DOD分成多个区间DOD越深、单位退化成本越高本质上就是把幂函数用分段直线逼近。实际复现中我先用线性版本跑通全流程再扩展成分段版本两者差距一般控制在几个百分点以内但计算复杂度差异明显。这个环节也是复现时观感变化最大的地方。不考虑衰减成本时优化算法为了让储能套取峰谷价差会让SOC像锯齿一样频繁冲到上限、再放回下限加入退化成本后SOC曲线自然变得平缓充放电次数显著减少系统在“多调节”和“少损耗”之间找到了折衷。这一眼就能看出衰减建模的价值。4. 调度模型落地目标函数与约束的取舍4.1 目标函数四个成本项怎么放到同一个天平上多时间尺度调度模型本质上是一个混合整数线性规划MILP问题。目标函数是所有决策时段上的成本总和我按论文的设定拆成了四部分。第一部分是发电机组成本包括燃料成本和启停成本。燃料成本通常用线性或二次函数近似二次项在MILP里处理起来麻烦实际中常分段线性化。第二部分是与主网的交易成本虚拟电厂在几个时段从主网购电、在另一个时段向主网购售电。第三部分是储能退化成本就是我上一节说的λ_deg乘吞吐量。第四部分是弃风弃光惩罚和失负荷惩罚这两个惩罚项保证了优化不会为了省成本而随便扔掉新能源或牺牲负荷。表达式写成min Σ_t [ C_fuel(t) C_start(t) C_grid(t) C_deg(t) C_penalty(t) ]四个成本项放在同一个目标函数里时难的不是写出来而是系数怎么定。弃风惩罚单价如果定得太低系统会主动选择弃风而不是调用储能结果是风光消纳率难看如果定得太高系统又会不计代价地压缩机组出力、深度调用储能造成机组运行点极不合理或储能寿命损耗飙升。通常的做法是先参考论文的参数范围再通过灵敏度分析找到合理的数量级。4.2 约束条件别让模型只在纸面上可行约束条件决定了优化结果在现实中是否可执行。基本约束包括功率平衡约束、机组出力上下限、机组爬坡约束、最小启停时间约束、储能SOC动态方程、SOC上下限、充放电功率限制以及虚拟电厂与主网之间的联络线功率限制。功率平衡约束是最基础的等式约束所有发电出力、储能放电量、主网购入电量之和等于负荷加上储能充电量。这个等式在求解器里必须被严格满足否则模型会利用不平衡来降低成本。机组爬坡约束则限定了相邻时段之间出力的最大变化量它直接决定了系统能否跟上净负荷的快速波动。储能部分的约束需要注意一个细节SOC动态方程写作 SOC(t1) SOC(t) [η_ch × P_ch(t) − P_dis(t)/η_dis] × Δt / E_rated。充放电效率η_ch和η_dis通常不相等如果用同一个效率值会高估储能的实际可用能量。另外SOC上下限不应设成0%和100%实际工程中为了保护电池和应对突发情况往往限制在10%~90%之间这个区间也影响调度方案的灵活性。为了保证模型在极端场景下不会因为无解而崩溃我在约束里加了一个松弛变量功率平衡约束改为等式右边可以出现一个小的松弛量松弛量进目标函数并给予很高的惩罚系数。这样极端场景下求解器给出的是“成本最优的近似可行解”可以继续分析而不是直接输出“infeasible”。这一招在日内滚动和场景法计算中特别重要。4.3 折衷机制三个旋钮决定系统是“惜用”还是“硬扛”模型跑通后最有意思的部分是观察灵活性与成本之间的拉锯如何被三个参数控制。第一个旋钮是备用需求系数α。调度模型可以在每个时段要求系统预留一定比例的上调备用比例越高系统应对净负荷预测误差的能力越强但代价是更多机组不能工作在最优出力点储能也要保留更多可充电空间。第二个旋钮是退化成本系数β它乘在储能退化成本上。β设为0时储能被视为零成本资源调度器会不计后果地让它充放β调大后储能的“身价”变贵调度器就会尽量减少它的动作把电量留给真正的关键时段。第三个旋钮是弃风弃光惩罚单价γγ越高系统越倾向于调用昂贵机组和储能来消纳新能源。我复现时做了一组对照大概结果如下表。注意这是简化数值不具有普适性但可以说明趋势。策略退化成本储能等效循环次数弃风率灵活性不足时长不考虑衰减忽略高低低线性衰减计入中中中衰减加权提高β后计入明显降低升高略有上升这张表最核心的信息是储能成本被更准确地纳入优化后系统会“少动储能、多动机组”甚至在某些极端时段接受弃风。大量论文把这种现象总结为“用经济手段抑制储能滥用”实际算例证明效果非常显著。我在复现中把β从1倍调到3倍储能的等效循环次数下降了大约四成而总成本只上升了不到一成这让“储能是否值得多配”这个问题有了量化的答案。5. Matlab代码实现的关键环节与避坑记录5.1 代码架构别一上来就把所有约束塞进一行复现这类模型的代码最忌讳把所有约束写在一个巨大的方括号里。我最终的Matlab工程采用四层结构。主入口脚本负责设置算例参数和调用各模块数据生成模块负责生成负荷曲线、风光预测曲线、预测误差场景建模与求解模块负责用优化建模工具构建变量、约束和目标函数结果可视化模块负责出图和分析指标。模块化的好处在调试时体现得特别明显。某个约束导致无解时我可以单独注释掉一组约束测试变量和系数是否正确SOC轨迹异常时我可以只检查储能约束模块不用在整个模型里翻找。对于刚上手的同学我建议每个约束单独写成一个函数端口只留变量和参数结构体。虽然前期代码量多一点但后面换算例、换时间尺度时几乎不用改动核心逻辑。5.2 从Yalmip建模到求解器调参的实战片段Matlab下我用Yalmip搭建模型求解器选择商业MILP求解器。核心代码风格大概是下面这样T 24; % 时段数 E_rated 10; % 储能容量 MWh SOC0 0.5; % 初始SOC eta 0.95; % 充放电效率简化对称 Pch sdpvar(T, 1); % 充电功率 Pdis sdpvar(T, 1); % 放电功率 soc sdpvar(T1, 1); % SOC曲线 Constraints []; % SOC初值 Constraints [Constraints, soc(1) SOC0]; % SOC动态 Constraints [Constraints, soc(2:end) soc(1:end-1) (eta*Pch - Pdis/eta)/E_rated]; % 充放电功率与SOC上下限 Constraints [Constraints, 0 Pch 5, 0 Pdis 5]; Constraints [Constraints, 0.1 soc 0.9]; % 目标函数省略机组部分 Objective sum(deg_cost_per_mwh * (Pch Pdis)); % 退化成本 options sdpsettings(solver, gurobi, mipgap, 0.01); optimize(Constraints, Objective, options);这段代码虽然简单但能跑通一个最小闭环。真正项目中会把机组启停变量、爬坡约束、联络线约束、备用约束都加上。求解器的设置里我习惯把mipgap设为0.01而不是默认的0因为米级变量成百上千时硬求最优会让求解时间从几秒涨到几分钟而1%的gap对结果影响很有限。5.3 绕不开的五个坑每一个我都踩过第一个坑是SOC初值没有跨尺度传递。多时间尺度滚动优化时日内优化必须把日前计划最后一个时段的SOC当作初值传进来否则SOC曲线会出现不自然的跳变。我的做法是每个优化阶段结束后用实际量测值更新一个状态结构体下一阶段从里面读取。第二个坑是退化成本项里的绝对值不好处理。部分论文把退化成本写成与SOC变化绝对值成正比但绝对值在MILP里需要用辅助变量线性化。引入非负辅助变量d并添加约束d ≥ SOC(t1)−SOC(t)、d ≥ SOC(t)−SOC(t1)再把d加入目标函数。这个手法很小但如果不知道很容易卡在求解器报“非凸”错误上。第三个坑是储能充放电同时不为一。物理上同一时刻既充电又放电是浪费如果目标函数里没有对充放行为施加成本求解器偶尔会输出两边同时为正的奇怪解。最稳妥的方法是引入一个二进制变量标志储能状态约束Pch ≤ M×u、Pdis ≤ M×(1−u)。某些场景可以用效率惩罚来避免但加二进制变量最直接代价只是多一组整数变量。第四个坑是场景法求解时变量规模爆炸。复现论文中经常要生成几十个随机场景模拟风光预测误差如果每个场景都复制全部约束MILP规模会膨胀到求解器难以承受。我用拉丁超立方生成200个初始场景再用同步回代削减成5到8个典型场景在计算精度和求解时间之间取得了很好的平衡。第五个坑是模型无可行解的定位难。出现infeasible时第一步要看是不是SOC约束和功率约束互相矛盾第二步检查备用约束是否过紧第三步检查机组最小启停时间是否把启停状态锁死。我最终采用的办法是加松弛变量并用高惩罚系数兜底让模型永远“有解”再通过松弛量大小判断真正的瓶颈约束。6. 从论文公式到可跑通的代码我的复现工作流6.1 读论文时我做三步拆解避免瞪着公式发呆拿到一篇带数学模型的论文最怕的是直接冲着公式看看完一个都记不住。我的做法是三步拆解。第一步把论文里的模型公式抄到纸上用不同颜色标记三类内容决策变量、不可调节参数、中间变量。绝大多数论文不会把所有参数写全很多参数藏在算例表格里或图表旁白里需要自己补齐。第二步从最简版本开始实现先忽略不确定性假设预测完全准确跑一个单时段的确定性优化这个版本求解快、逻辑透明能验证目标函数和约束的基本正确性。第三步逐步增加复杂度加多时段、加储能衰减成本、加场景不确定性、加多时间尺度滚动。每加一个模块就跑通一次避免所有问题堆到最后一起爆炸。6.2 验证模型是否真的可靠结果可视化与指标对照跑通代码只是第一步更重要的是验证结果在物理上是否合理。我每次完成一组算例都强制看四个图各机组出力和净负荷曲线叠在一起看功率平衡是否闭合储能SOC轨迹看有没有不合理跳变或频繁满充满放弃风量和弃风率柱状图看新能源消纳水平总成本构成堆叠图看各项成本的占比变化。这四个图基本能把模型有没有“学坏”暴露无遗。在做对照时我保留了一组论文中的标准算例用同样的参数设置去复现。因为环境假设略有差异完全一致很难但成本变化的趋势和主要调度行为应该对得上。特别要看储能等效循环次数和弃风率这两个敏感指标如果它们与论文偏离太大通常意味着某个成本系数或效率参数设置有误。6.3 这个模型还能往哪些方向扩展复现完主体模型后我顺手做了两个扩展。一是把线性退化成本换成按DOD分档的分段线性成本这能让SOC在低荷电状态附近的行为更保守二是把柔性和电动汽车充放电聚合进去作为额外的可调资源。扩展之后的模型体系还支持后续换成分布鲁棒或机会约束求解不需要推翻原有代码框架。对于刚接触这个方向的同学我的建议是别急着追求复杂的求解算法。先把确定性的多时间尺度模型和衰减建模吃透再把不确定性纳入这个顺序几乎不会被推翻。模型不复杂但参数之间的相互影响需要大量实验才能摸清纸上推演只能看到方向真正让成本曲线发生变化、让SOC轨迹变得平滑的永远是那些看似不起眼的惩罚系数和效率值。我在实际复现中最大的体会是储能衰减必须写进目标函数而且是研究的必要条件不是锦上添花。忽略它调度方案会变得非常激进计算出的成本比实际偏低20%以上这种“便宜”在真实项目中根本不存在。而一旦把退化成本放进去你就能很自然地回答标题里的那个问题灵活性不是靠买更多的储能堆出来的而是靠合理地给每一次调节行为定价逼着调度器在“多调节”和“少损耗”之间找一个真实存在的交点。最后再分享一个实用技巧所有参数不要写在脚本里单独用一个结构体集中管理我做灵敏度分析时只需要改一行参数整个实验流程就能批量重跑省掉的时间远超写这行代码的投入。

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

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

免费获取报价 →
↑