资讯动态

计及新能源不确定性的综合能源系统协同优化:场景法与Matlab实现

发布时间:2026/10/15 8:56:23 来源:尧图企业网站定制
新能源出力的随机性对综合能源系统的影响往往要到实际算例跑崩之后才让人真正重视。我最初做某园区级综合能源系统优化时用的还是标准的确定性调度模型光伏和风电出力取预测曲线直接代入优化求解。结果有一天模拟场景里光伏实际出力比预测低了将近四成储能又刚好在低谷时段放空了电系统直接切了一部分负荷那天的运行成本比预期高出将近一倍。从那之后我意识到计及新能源出力不确定性不是锦上添花的加分项而是综合能源系统协同优化能不能落地的前提。这篇文章就把我在这类项目里的建模思路、算法取舍和Matlab代码实现过程完整梳理一遍。文章主要面向正在做电气设备综合能源系统调度、微电网能量管理或者虚拟电厂优化的同学和工程师。如果你已经能跑通常规的确定性优化但不知道如何处理风电、光伏的随机波动或者你已经在用场景法但不太清楚场景削减、求解器配置这些细节怎么处理那这篇内容应该能直接给你省出不少试错时间。我尽量把每一步的“为什么这样做”也讲清楚而不只是丢一个能跑的代码出来。1. 为什么“计及不确定性”实际决定了综合能源系统优化成败1.1 确定性调度在真实波动面前的脆弱性先从一个最常见的场景说起。典型综合能源系统里通常包含光伏、风电、热电联产机组、燃气锅炉、电储能和热储能系统通过一个能量管理中心统一调度。这些设备之间存在强耦合热电联产机组的电出力会受热负荷约束牵制储能既要参与电力平衡也可能参与热力平衡而新能源的随机波动又会把所有设备的出力计划一起带偏。如果优化模型里的新能源出力全部按预测曲线处理调度计划看起来是完美的每个时段功率都平衡、成本也最低。但实际运行中光伏和风电的出力与预测值之间往往相差20%到40%尤其夏天雷阵雨和冬天大风天气波动幅度会更大。一旦实际出力不达标原本最优的调度方案就变成电力缺口方案、热力失衡方案。我在某个模拟算例里做过对比同一套系统、同一个负荷曲线确定性方案得出的日运行成本是5.2万元但把这个方案放到100组抽样生成的“真实出力”场景里回放平均实际成本变成了6.8万元最差的一组甚至到8.1万元。成本上涨的直接原因有两个一是缺电时段被迫从外网购高价电二是弃风弃光量增加导致清洁能源利用率下降。这两块恰恰是综合能源系统经济性的核心来源。所以现在我处理这类问题时的原则很简单不确定性必须在优化模型内部处理而不是事后修正。要么用场景法让模型提前看到多种可能要么用鲁棒优化把最坏情况兜住。1.2 计及不确定性之后优化结果会发生什么变化把不确定性引入模型后优化结果不会只体现在成本数字上。从我的实测算例来看至少有三个明显变化第一储能充放电策略变得更“保守”。确定性方案里储能会在某些时段满充满放来赚取峰谷差但计及不确定性后模型会倾向于保留一部分电量作为备用容量用来应对光伏突然减出力的情况。这种保守不是缺点而是风险代价的真实反映。第二机组出力计划会更平滑。因为要照顾到多个场景同时可行优化出的机组出力不再贴着上限或下限走而是留出一定的调节空间。爬坡速率约束在不确定性模型里起的作用也比确定性模型更大试过就想得到场景一要求你爬上去场景二要求你降下来如果爬坡跟不上模型就会自动把出力压在一个折中区间。第三购电策略从“只看电价”变成“综合考虑风险”。计及不确定性后同一时段外网购电价格低系统也不一定满负荷购电因为它还要考虑风光出力可能偏高导致弃电惩罚增加。这些变化加在一起最终得到的调度方案牺牲了一部分理想状态下的经济性换来了对波动场景的适应能力。这个取舍是否划算取决于系统的新能源渗透率。渗透率低波动影响小确定性和不确定性结果差异不大渗透率高比如超过30%之后不确定性模型的价值就非常明显了。我做过的项目里新能源渗透率40%左右的系统用场景法优化后最差场景下的成本比确定性方案减少了约22%这个改善幅度完全可以覆盖建模和求解增加的时间成本。2. 协同优化的数学骨架目标函数、决策变量与耦合约束2.1 目标函数怎么设计才能兼顾经济性与清洁性综合能源系统协同优化的目标函数不能只写一个购电成本。我做这个模型时目标函数包含四部分每一项都有实际意义外网购电费用按分时电价计算体现系统与外部电网的交互成本天然气购气费用用于热电联产机组和燃气锅炉按热值折算成单位成本储能充放电损耗成本储能每次充放都有寿命折损按等效循环寿命换算成成本避免模型只盯着峰谷价差让储能过于频繁动作弃风弃光惩罚项电价低或负荷小时模型容易选择削减新能源出力但这与清洁能源消纳目标相悖所以加惩罚项引导模型优先消纳新能源。除此之外如果项目有碳排放考核还可以加碳排放成本项。我建议一开始不要把所有目标都堆进去先跑通经济性目标再叠加碳排放目标缩小问题规模的同时也方便排查问题。目标函数形式可以写为objective sum(购电价格 .* E_buy) gas_price * V_gas ... k_storage .* (P_ch P_dis) ... penalty * (P_PV_available P_WT_available - P_PV - P_WT);这里的P_ch和P_dis是储能的充放电功率P_PV_available和P_WT_available是场景里光伏和风电的可发功率实际调度出力不能超过这个值差值就是弃电乘上惩罚系数后进入目标函数。2.2 多能耦合约束是模型里最容易出错的部分综合能源系统和单纯电力系统最大的区别在于耦合约束。我踩过的坑主要集中在三处第一处是热电联产机组的热电比约束。燃气轮机在发电的同时产生余热余热回收后供给热负荷但热出力不是随便取的它和电出力之间有一个可行域关系。我看过不少新手直接把热出力和电出力分别当作独立变量处理结果优化出来一个“电出力很高、热出力很低”的不合理工况实际物理过程根本无法实现。更准确的建模方式是用热电联产机组的可行运行区间来描述通常是一个多边形区域由最小电出力、最大电出力、最小热出力、最大热出力以及热电比共同确定。第二处是储能设备的时序耦合。储能系统的约束必须跨时段耦合每个时段的SOC等于上一时段SOC加上充电效率乘充电功率再减去放电效率的倒数乘放电功率。这个约束看起来简单但实际建模时很容易写错下标或者漏掉充放电互斥约束。我建议用0-1变量表示充放电状态加入约束P_ch M * u_ch和P_dis M * u_dis同时u_ch u_dis 1这样才能保证模型不会出现同一时段既充电又放电的情况。第三处是热力系统的慢动态特性。热负荷和电负荷不同热能传输和建筑蓄热都有惯性热负荷波动不像电负荷那样需要瞬时平衡。如果完全按照即时平衡约束去建热网模型系统会要求锅炉频繁启停求解结果看起来很“聪明”但工程上不现实。我处理的方式是允许热力系统存在一定范围内的热惯性缓冲把热平衡约束改写成带有松弛变量的软约束。这样做求解速度会更快结果也更具操作性。2.3 典型系统架构与变量定义我用来做仿真的典型系统构架如下光伏阵列和风电机组直接并网热电联产机组供电并产热燃气锅炉作为热力备用电储能和热储能分别承担电、热时段平移功能。系统通过上级电网的联络线购电天然气由配气管网供应。决策变量大致分为三类连续变量各机组出力、储能充放电功率、购电量、购气量、热储能充放热功率0-1整数变量机组启停状态、储能充放电状态不确定性变量各场景下光伏、风电的功率值。把不确定性和0-1整数变量一起放进模型之后问题就变成一个混合整数线性规划问题MILP。如果目标函数和约束都是线性的——这要求对风电功率曲线做分段线性化处理——就可以用成熟的商用求解器高效求解这也是为什么我坚持把模型整理成线性形式而不去写非线性版本的原因。3. 新能源出力不确定性的处理思路场景法、鲁棒法与机会约束3.1 三种方法的核心思想与适用场景处理新能源出力不确定性行业内主流方法有三种我分别说一下它们的实际体验。场景法随机规划先通过历史数据和概率分布生成大量出力场景再把目标函数写成“各场景成本之和乘以场景概率”的形式让每个场景下的约束都得到满足。这种方法逻辑最直观代码也好写缺点是需要兼顾求解规模场景太多时会变成沉重的计算负担。鲁棒优化不确定参数被描述成一个区间或集合模型优化的是“最坏情况下的成本”约束要求在集合内所有参数取值下都成立。这种方法求出的解最保守运行成本通常最高但它不需要知道不确定参数的概率分布只需要一个波动范围就行。对有安全约束的系统鲁棒优化可以确保任何时候系统都不越限。机会约束规划允许约束在不超过给定概率的前提下被违背比如“电压越限概率不大于5%”通过把概率约束转化为确定性的分位数约束来求解。这是介于场景法和鲁棒法之间的折中方案理论上很优雅但实现起来要处理概率分布的解析转化非线性程度通常更高。我在实际项目里经常采用的做法是如果系统安全约束要求硬性满足就采用两阶段鲁棒优化如果只是经济调度问题优先使用场景法。原因很现实——场景法的求解速度快代码维护方便而且可以通过场景削减技术把计算量控制住。鲁棒优化的结果更保守在新能源渗透率不高时过度保守带来的成本增加并不划算。3.2 常用场景生成与削减技术详解场景法要落地场景生成和场景削减是两个绕不开的环节。我用的是这样一条链路第一步根据历史出力数据拟合光伏出力的Beta分布和风速的Weibull分布再通过功率转换曲线得到风电出力分布。需要注意光伏Beta分布是建立在晴朗指数基础上的不能直接对功率值本身拟合Beta分布。第二步用拉丁超立方采样从分布中抽取样本。相比用蒙特卡洛随机抽样拉丁超立方采样能保证采样点在概率空间里分布更均匀覆盖到分布的尾部区域这是蒙特卡洛很难做到的。我一般先抽2000到3000个场景作为初始场景集。第三步是场景削减。直接带2000个场景进优化问题会让模型非常大一个24时段系统就可能有几十万个约束求解时间动辄数小时根本没法快速迭代。场景削减最常用的是同步回代削减法Simultaneous Backward Reduction。核心逻辑很简单重复删除与其他场景概率距离最近的场景并把这个被删场景的概率加给距离它最近的那个场景。最后只保留10到20个典型场景就能覆盖绝大多数概率质量。我算过一组实际数据把2000个场景削减到20个典型场景削减速率为99%但调度结果与用完整场景集求解的成本偏差只有约3%。这说明在调度层面少量典型场景已经足够表达不确定性特征不必为了追求场景数量而牺牲求解效率。3.3 典型场景校核的四个维度场景减完不是直接用就完事我每次都会做四个维度的校核概率和是否还是1同步回代削减后典型场景的概率之和应该仍然是1如果不是说明步骤写错或者削减过程中概率转移有遗漏各场景出力均值是否接近原始分布的均值如果削减后的典型场景均值比原始分布均值偏出太多说明削减过度了典型场景没有保留原始统计特征极端场景是否存在光伏出力的尾部高出力场景和风电的零出力场景一定要保留否则模型会设计得过于乐观缺少应对极端波动的能力场景之间的相关性是否失真风光出力往往存在负相关性削减后要检查典型场景对负相关性的还原程度如果完全失真协同优化的结果也会失真。这四个维度的校核半小时内可以完成但这半小时能避免后面整天的排错时间。4. Matlab实现的核心模块设计与求解流程4.1 代码整体架构与模块划分整套Matlab代码我建议按照模块化来组织不要写成一个巨大的脚本。我常用的目录结构如下load_data.m读入负荷曲线、分时电价、天然气价格、设备参数、风光历史出力数据generate_scenarios.m基于历史数据生成新能源出力场景并削减build_model.m用Yalmip工具箱构建目标函数和约束生成优化模型solve_model.m调用求解器求解MILP问题并检查求解状态plot_results.m绘制各设备出力曲线、储能SOC曲线、购电曲线等run_case.m主程序依次调用上述模块并输出结果。这里有一个很有争议但实际效果很好的选择我用Yalmip而不是直接手写linprog或者intlinprog的矩阵形式。Yalmip给每个约束起名字的方式非常直观比如Constraints [Constraints, SOC(2) SOC(1) eff_ch*P_ch(1) - P_dis(1)/eff_dis];读起来几乎就是数学公式调试的时候哪条约束出问题一目了然。如果直接写稀疏矩阵约束34个时段加上20个场景的模型光索引对位就能让人崩溃。4.2 核心建模代码片段解析这部分是整篇文章的核心我把关键代码片段的思路拆开来讲。第一个关键片段是场景生成后的数据组织格式。我喜欢用三维矩阵来存场景数据P_PV_scene(t, s)表示场景s下第t时段的光伏可发功率P_WT_scene(t, s)同理。这样后面的约束就可以写成对所有场景统一生效的形式。第二个关键片段是各时段各场景的功率平衡约束for t 1:T for s 1:S Constraints [Constraints, ... P_buy(t,s) P_CHP(t,s) P_PV(t,s) P_WT(t,s) P_dis(t,s) ... P_load(t) P_ch(t,s)]; end end注意这里负荷曲线P_load(t)默认是确定的如果负荷本身也有波动可以再把负荷场景也生成一组但为了控制模型规模我通常先固定负荷。第三个关键片段是储能SOC的时序递推。Constraints [Constraints, SOC(1) SOC_init]; for t 2:T for s 1:S Constraints [Constraints, ... SOC(t,s) SOC(t-1,s) eta_ch * P_ch(t,s) - P_dis(t,s) / eta_dis]; end end Constraints [Constraints, SOC(T,s) SOC_init]; % 调度周期始末SOC一致有些文献里不加“始末SOC一致”这个约束但实际调度周期结束后储能SOC不能随意变化否则下一个调度周期无法衔接。加了这条约束后储能必须在周期内完成一次完整的充放循环结果更符合工程实际。第四个关键片段是目标函数中对多个场景的期望成本表达。objective 0; for s 1:S objective objective prob(s) * ( ... sum(price_buy(t) .* P_buy(t,s)) ... gas_price * sum(L_gas(t,s)) ... k_storage * sum(P_ch(t,s) P_dis(t,s)) ... penalty * sum(P_PV_available(t,s) - P_PV(t,s) P_WT_available(t,s) - P_WT(t,s))); end把所有场景的目标期望值相加模型就会在优化过程中自动权衡不同场景之间的成本而不是只照顾某一个场景。4.3 求解器配置与求解状态处理Yalmip建模完成之后求解器我优先选Gurobi或者Cplex这类商用求解器Matlab自带的intlinprog可以作为备选。两者的性能差距在中小规模问题上还不明显但一旦场景数到了15以上、变量数突破5000之后差距就非常显著了。求解器配置要注意几个关键参数MIPGap设为0.01%也就是1e-4允许1%的最优性偏差可以大幅缩短求解时间TimeLimit设为300秒超过时间限制后返回当前最优可行解对偶策略和割平面策略使用默认值即可自定义反而容易引入问题。我遇到过求解器返回Infeasible不可行的情况。排查方法很简单先把新能源出力设成预测期望值看问题是否变得可行如果可行说明是某些不确定场景下的约束太紧了具体来说不是储能爬坡约束太紧就是热电联产机组的可行域太小需要适当放宽发电区间。假如连确定性情况也报不可行那就是设备参数没写对比如最小出力大于了最大出力或者储能的SOC上下限和初始值矛盾。5. 算例复盘典型日调度结果与三个实操陷阱5.1 一个典型日调度结果能说明什么用削减后的15个典型场景跑完一个全天24时段的调度输出结果的判读也有讲究。我习惯看四张图各设备电出力堆叠图、储能SOC曲线、热出力曲线、购电曲线。这四张图基本能定位90%的问题。以我跑的一个算例为例夜间负荷低谷时段储能主要充电、热电联产机组降出力运行这是正常现象白天光伏大发时段光伏出力占据主导购电量会明显减少到了晚高峰储能放电叠加热电联产机组满发购电曲线仍会有一段峰值。如果发现哪个时段购电量异常高或者机组出力出现频繁启停的锯齿状一般就是约束或目标函数里出了问题。三张图形状的“合理感”也很重要。比如说储能SOC曲线如果出现锯齿状高频振荡说明价格信号在驱动储能反复吞吐这通常是因为分时电价时段切换太密储能折损成本设置过低需要调高k_storage参数。5.2 实操陷阱一场景削减后概率失真我第一次做场景削减时踩过一个很典型的坑削减后尽管总概率保持为1但风电典型场景里缺少了低风速时段导致模型完全没考虑风电不出力的可能性。结果就是系统在无风场景下出现功率缺口备用容量不足。解决方法是按我前面提到的四个维度去做校核尤其是要把“极端场景”手动加回典型场景集里。手动添加极端场景后再重新归一化概率这会让模型对极端天气更有耐心。5.3 实操陷阱二求解时间过长15个场景、24时段、约40个变量、20个0-1变量规模其实不大但如果不做任何优化求解器可能需要几分钟才能收敛。如果场景数加到30求解时间可能会暴涨到半小时以上。我控制求解时间有三个手段把MIPGap放宽到1%用热启动策略先跑一个确定性调度作为初始解传给MILP求解器减少不必要的0-1变量比如储能的充放电互斥约束如果储能折损成本设置恰当目标函数本身就不鼓励同时充放可以尝试把0-1变量松弛掉。第二种方法对模型改动最小求解效果提升也最明显。5.4 实操陷阱三模型灵敏度参数意义不清晰目标函数里的惩罚系数penalty、储能折损系数k_storage这些参数如何取值直接决定优化结果的价值取向。penalty设置太大会导致模型不计代价消纳新能源甚至让系统在电价极高时还保持光伏满发设置太小又会让弃风弃光率过高。建议用控制变量法做一次敏感性分析并画曲线取拐点位置作为参数取值依据。我做敏感性分析的经验是画“弃风弃光率-惩罚系数”和“运行成本-惩罚系数”两条曲线两条曲线交点附近往往是比较合理的惩罚系数取值区域。这个做法比“凭经验给个值”要靠谱得多。6. 一点个人体会把计及新能源出力不确定性的综合能源系统协同优化从建模做到Matlab代码实现最直观的感受是模型表达不确定性的方式决定了系统的经济边界和安全边界。场景法入门门槛最低只要熟练掌握缩减法就能在效率与精度之间取得合理平衡鲁棒优化适合安全约束严格的场合但要注意它的保守代价机会约束理论上更优雅但工程实现里非线性的转化成本往往比想象中更高。代码落地阶段模块化组织、Yalmip建模、商用求解器组合几乎是当前做这类优化最顺手的路径。做这一块项目真正决定方案能用与否的其实不在求解器性能而在于那些消耗时间的隐性工作场景校核、参数敏感性分析、约束合理性的验证。刚开始做不确定优化时我建议先跑通一个带10个场景、单时段的小模型把每个环节的输入输出都对清楚再扩展到完整24时段模型。等看到风电出力不确定场景下储能预留出合理的调节裕度、外购电曲线不再贴着电价下限走的那些瞬间你会觉得前面所有排错都值得。

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

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

免费获取报价 →
↑