高比例可再生能源电力系统调峰成本量化与分摊的Matlab实现
发布时间:2026/9/12 18:47:15 作者:尧图编辑部 阅读量:1,286

最近一个多月我都在折腾高比例可再生能源电力系统的调峰成本量化与分摊模型Matlab代码前前后后改了三版。这类问题在学术上很好描述真正落地时全是细节谁来承担调峰成本、按什么标准分摊、代码怎么组织才能让结果可解释。很多同学拿到题目第一反应是“这不是个优化问题吗”等真正把约束写进去、把求解器跑起来才发现难点压根不在求解而在“成本归因”这件事本身。这篇文章就把我完整的建模思路、Matlab实现过程以及踩过的坑一次性讲清楚适合正在做相关课题、写毕业论文或者做工程仿真的朋友直接参考。1. 调峰成本为什么要单独量化不能混在总成本里1.1 高比例可再生能源改变了电力系统的成本结构传统电力系统里火电、水电这些常规机组是主角负荷变化是主要扰动调度层只需要做一件事在满足安全约束的前提下让机组组合和经济调度总成本最小。风电和光伏大规模接入后系统的扰动源从“负荷侧”扩展到了“源荷双侧”净负荷曲线负荷减去可再生能源出力的波动幅度和变化速率都显著增加。简单说以前一天里的净负荷曲线比较平滑早高峰晚高峰也就两个坡现在叠加了风电出力的大幅波动和光伏的午间猛增净负荷可能出现“鸭子曲线”甚至多个峰谷。常规机组被迫频繁启停、快速爬坡甚至在低出力区间长时间运行这些操作都会带来额外的运行成本。这部分因为可再生能源接入而额外增加的成本就是调峰成本的来源。调峰成本不单独量化会产生一个实际问题可再生能源多了系统总运行成本可能反而上升但上升的部分到底该记在谁头上说不清。对电网公司来说调峰服务需要给机组补偿补偿依据是什么对风电场光伏电站来说分摊标准是什么总不能一刀切按电量均摊。所以必须先有一套可计算、可追溯的调峰成本量化方法然后才能谈分摊。1.2 给调峰成本划清单哪些该算哪些不该算我在建模前先拉了一张成本构成清单把调峰相关成本分成四类后续所有目标函数和约束都围绕这四类展开。第一类是燃料成本。机组在深度调峰区间运行时煤耗率往往比额定工况高单位电量的燃料成本上升。这个最直观用二次成本函数分段线性化即可描述。第二类是损耗与寿命成本。机组频繁爬坡、低负荷运行、启停都会造成高温部件热应力变化累积疲劳损耗。工程上常把深度调峰造成的机组寿命折损折算成运维成本以小时为单位叠加进运行成本。这个项如果省略结果会明显偏低。第三类是启停成本。风电大发导致机组压负荷甚至停机风电小发时又需要快速启动。每次启动有燃料消耗、锅炉助燃等成本频繁启停是调峰成本里很重要的一部分。第四类是备用与弃电成本。为了应对预测误差和净负荷快速波动系统要预留更多旋转备用备用的机会成本要分摊极端情况下需要弃风弃光弃电损失也应作为调峰失灵的代价计入。这四类成本不可能全部由机组自己扛也不可能让可再生能源主体白白受益量化和分摊就是解决“钱从哪来、往哪去”的问题。2. 调峰成本量化模型的设计思路与数学建模2.1 先想清楚用“差分法”分离调峰成本而不是直接建模我在一开始也犯过迷糊试图直接在目标函数里把“调峰成本”设成一个变量结果发现根本分不清哪部分成本算调峰、哪部分算发电。后来采用了工程上常用也更容易在论文里讲清楚的差分法思路。具体操作分两步。第一步用真实的负荷曲线和常规机组参数建模“无风光接入”的基准调度场景求得基准运行成本第二步把风电场和光伏电站的出力曲线叠加进系统重新做同样的机组组合与经济调度得到含可再生能源场景下的总运行成本。两个场景的运行成本差就是由可再生能源接入带来的调峰成本增量。这种方法的优势在于基准场景和实际场景使用同一套机组模型和求解算法成本差异纯粹来源于净负荷特性变化结果有很强的可比性。缺点也很明显——做了两次求解计算量翻倍而且“基准场景”本身存在定义争议。我处理的方法是基准场景中可再生能源出力置零但保留同样的预测误差概率分布这样得到的是系统应对同样不确定性时的成本基线比较公平。2.2 目标函数与约束条件的具体数学表达整个量化模型可以描述为一个两阶段问题先做日前机组组合再做日内经济调度。Matlab里我直接用混合整数规划框架统一处理目标函数如下其中第一项是常规机组出力相关的燃料成本第二项是深度调峰运行附加成本第三项是机组启停成本第四项是备用容量成本第五项是弃风弃光惩罚。注意这里有一个容易被忽略的点备用成本不能只按备用容量乘单价还应该考虑备用调用概率否则高估太多。约束条件我列了八组功率平衡约束、机组出力上下限含深度调峰区间、爬坡率约束、最小启停时间约束、旋转备用容量约束、线路潮流约束如果有网架、储能充放电约束如果有储能、弃风弃光比例上限约束。这些约束里有几个细节值得展开讲讲。机组出力上下限不是简单一个区间。我把火电机组划分成常规运行区间和深度调峰区间常规区间是最大技术出力到最小技术出力深度调峰区间是最小技术出力到更低的稳燃出力两个区间对应不同的单位煤耗和损耗成本系数。这个处理在代码上是通过分段线性成本函数实现的约束本身没有增加难度但对结果影响很大。爬坡率约束在高比例可再生能源场景下很容易成为瓶颈。风电波动快要求火电快速增减出力而爬坡能力有限。我建议在约束里显式加上爬坡率限制同时配合上一时间断面的净负荷变化量来预判瓶颈时段。2.3 那些让结果“失真”的参数陷阱建模过程中我踩过几个参数陷阱非常值得提醒。第一时间分辨率不能太粗。有人图省事用小时级数据建模风电和光伏的快速波动被平均掉调峰成本会被严重低估。我实测过用1小时和15分钟粒度的数据跑同样场景15分钟粒度算出的调峰成本比小时级高出20%左右。建议至少用15分钟粒度。第二旋转备用需求要区分上调备用和下调备用。风电低估时系统需要上调频率控制备用而光伏午间出力大增时反而需要下调能力不能用同一个容量数值。第三深度调峰损耗成本系数没有统一标准需要根据机组类型和运维数据进行标定。文献里常见的是按运行小时数折算成等效满负荷运行小时损失这个系数我用前专门查了所研究机组类型的典型取值范围。3. Matlab代码实现从数据准备到优化求解的完整流程3.1 代码整体结构与数据组织方式Matlab实现这类模型第一步不是写优化代码而是把数据组织好。我用了四个结构体变量存放输入数据分别对应机组、负荷、新能源和系统参数这样后续维护成本很低。机组数据表包含机组编号、最大出力、最小出力、深度调峰下限、爬坡率、最小启停时间、燃料成本系数、启停成本、深度调峰损耗系数。负荷数据表是96点或24点的净负荷曲线新能源数据表是所有风电场和光伏电站的96点出力曲线系统参数表包含备用需求比例、弃电惩罚单价、基准功率等。这里有一个经验把所有单位统一成MW、MWh、元/MWh不要混用万千瓦和兆瓦否则结果几位数错了都不容易发现。我第一版跑出的结果大得离谱排查了半天才发现是风光出力单位MW负荷数据却用了万千瓦。3.2 用YALMIP搭建混合整数规划模型模型求解我用的是YALMIP加Gurobi的组合。YALMIP的好处是建模语言接近数学表达不用手动拼约束矩阵代码可读性好很多。如果你没有Gurobi用MATLAB自带的intlinprog也能跑小规模算例就是速度慢一些求解大规模系统容易卡死。核心代码如下。% 定义变量 on binvar(n, T); % 机组启停状态 su binvar(n, T); % 启动标识 sd binvar(n, T); % 停机标识 P sdpvar(n, T); % 机组出力 r sdpvar(n, T); % 备用容量 w sdpvar(nw, T); % 风电实际出力 pv sdpvar(npv, T); % 光伏实际出力 Constraints []; % 功率平衡 Constraints [Constraints, sum(P,1) sum(w,1) sum(pv,1) Load(1:T)]; % 出力上下限与深度调峰区间 for i 1:n Constraints [Constraints, Pmin(i)*on(i,:) P(i,:) Pmax(i)*on(i,:)]; Constraints [Constraints, P(i,:) Pdeep(i)*on(i,:)]; % 深度调峰下限 end % 爬坡约束 Constraints [Constraints, -Ramp(i) P(i,2:T) - P(i,1:T-1) Ramp(i)]; % 旋转备用 Constraints [Constraints, sum(r,1) ResReq(1:T)]; % 目标函数 Objective sum(sum(FuelCost(P))) ... sum(sum(DeepCost(P))) ... sum(sum(SucCost * su)) ... sum(sum(ResCost * r)) ... penalty * sum(sum(WindMax - w));这里我特意在目标函数里加了弃电惩罚项形式上等价于强迫系统优先消纳可再生能源但又不把弃电量设为硬约束。惩罚单价设得足够高比如2000元/MWh就能保证只有极端情况下才允许弃风弃光同时模型可解性更好。3.3 求解器选择与大规模加速技巧Gurobi跑小算例很轻松跑大系统就要注意技巧。我实测过96个时段、60台火电机组、10个新能源场站的全天机组组合模型变量在两万左右直接求解要一分多钟如果压缩成48时段、聚合同类机组二十秒就能出结果。如果你的算例规模更大建议采用滚动时段分解把全天分为若干个重叠区间每个区间单独求解区间之间用机组状态衔接。还有一个小技巧优先固定启停状态变量因为启停变量是整数变量中最难求解的部分。可以先忽略启停做经济调度得到近似最优出力和成本再以此为初值启发式生成较好启停组合把整数空间缩小。对没有商用求解器的场景可以选择线性化后的MILP并调用intlinprog。intlinprog求解速度虽不如Gurobi但它的优势是Matlab自带不需要额外配置。注意intlinprog要求所有变量输入为向量不能直接用二维矩阵建模需要把矩阵按列展开写起来会比较繁琐。4. 调峰成本分摊模型的设计与实现4.1 分摊原则先定游戏规则再谈比例计算成本量化是“算清账”分摊是“分好钱”。我在这部分花了很多时间参考实际电力市场中的补偿机制最终确定了三条分摊原则。第一是因果原则谁引起的调峰需求越大谁承担的成本越多。这是分摊模型的核心逻辑也是区别于平均分摊的关键。风光出力的波动性和预测误差是最主要的影响因素所以分摊权重应从波动性指标出发。第二是激励相容原则分摊金额不应大到让新能源项目无法盈利否则会抑制投资积极性。这里需要结合具体上网电价和度电成本来设定分摊上限。第三是可操作性原则分摊方法不能太复杂要让电网公司和电厂都能理解和复核。基于数学上很漂亮的Shapley值虽然理论完备但在众多场站参与时计算量极大工程落地难度高。我选择以边际贡献法为主体Shapley值法作为对照分析。4.2 三种可落地的分摊方法实现第一种是基于波动性指标的比例分摊法。对每个新能源场站分别计算其出力序列的标准差、最大爬坡速率和净负荷相关系数将三者归一化后加权求和得到该场站的调峰贡献系数再按贡献系数占总系数的比例分摊总调峰成本。第二种是基于场景差分的边际分摊法。先把所有新能源场站的整体出力曲线作为“全部参与”场景求得总调峰成本然后单独剔除一个场站重新计算调峰成本得到该场站的调峰成本增量。这个增量就是该场站的边际贡献。这个方法理论上严谨但需要重复n1次优化求解场站数量多时耗时很长。第三种是Shapley值法这里不展开具体公式了但它的核心思想是考虑“场站加入联盟的先后顺序”对每个场站计算其在所有联盟顺序下的平均边际贡献。对小规模案例少于8个场站可以在Matlab里直接穷举所有排列组合得到精确Shapley值规模变大后只能用随机采样近似。我在案例里用了一个简单的算例表格来对比方法结果。场站编号类型波动指标法分摊比例边际贡献法分摊比例Shapley值法分摊比例1风电33.6%31.2%32.4%2风电28.1%27.5%27.8%3光伏22.4%23.9%23.1%4光伏15.9%17.4%16.7%可以看到三种方法的结果接近误差在2个百分点以内这给了我信心在工程实践里用最简单的波动性指标法已经足够可靠边际贡献法和Shapley值更适合用在论文对比和争议仲裁场景。4.3 Matlab实现分摊模型的关键步骤分摊部分的Matlab代码可以独立于优化模型运行只要拿到第一步量化得到的总调峰成本和每个场站的出力序列即可。% 波动性指标计算 for k 1:nRenew stdRenew(k) std(Profile{k}); % 标准差 rampRenew(k) max(abs(diff(Profile{k}))); % 最大爬坡 corrRenew(k) abs(corr(Profile{k}, Load)); % 与净负荷相关性 end % 归一化 stdRenew stdRenew / sum(stdRenew); rampRenew rampRenew / sum(rampRenew); corrRenew corrRenew / sum(corrRenew); % 自定义权重可根据关注点调整 w1 0.4; w2 0.3; w3 0.3; share w1 * stdRenew w2 * rampRenew w3 * corrRenew; share share / sum(share); % 分摊成本 allocCost TotalPeakCost * share;这段代码虽然只有十几行但核心思想都包含了。实际使用时可能还要加入气象出力相关性和置信度修正比如某些场站存在同时性相关性高的场站要合并后再分摊否则会重复计费。这个细节我没有在初版实现中加入后来用实际数据测试时才发现同时率问题会导致某些场站分摊额明显偏高整改后结果更合理。5. 常见问题与排查技巧实录5.1 模型跑不出最优解先查这五个方面这类模型最常见的报错和异常我先列个清单后面逐一说明。总共有五类求解器报“infeasible”、结果出现大量弃电、成本出现负值、结果对初始值过度敏感、大规模运算卡死。求解器报“infeasible”时不要第一时间修改模型先把约束往宽处放开逐项排查。我通常先禁掉最小启停时间约束如果能解说明问题出在启停状态转换的时序约束上再检查初始时刻的机组状态设置是否正确。还要注意净负荷数据的首末时段边界如果日前调度时段从凌晨0点开始机组的初始状态和前一日的出力值都要预先赋值不能写NaN或零否则可能因为爬坡约束与初始状态矛盾导致无解。结果出现大量弃电要先检查备用约束是否过紧。我遇到过一次备用需求用固定“最大负荷的10%”计算结果在光伏大发时段系统下调能力不足被迫弃光。后来改用净负荷标准差动态计算备用需求弃电现象明显缓解。成本出现负数是最具迷惑性的问题。大多数情况是基准场景与实际场景的比较口径不一致。比如基准场景里没有考虑新能源出力的不确定性而实际场景考虑了或者基准场景的机组启停成本被覆盖掉一块导致总成本反而更低。我的经验是两个场景除了新能源出力曲线不同其他所有参数和约束必须完全相同。5.2 代码层面的排查技巧与效率优化我用Matlab写了几个自动化的验证脚本来辅助排查。第一个脚本检查所有输入数据的单位、范围、NaN情况第二个脚本在求解后检查每个约束的残差快速定位哪个约束被破坏第三个脚本对比连续两次运行结果用于识别非确定性因素。另外推荐一个小习惯在目标函数的每一项后面都加printf打印分别输出燃料成本、启停成本、深度调峰损耗成本和弃电惩罚项。有一次结果异常一眼就看到深度调峰损耗成本占了总成本的70%明显不合理排查后发现是损耗系数数量级别写错了从1e-4写成了1e-2。分开打印能让你很快锁定问题源头。代码运行效率方面我建议用向量化计算替代循环。YALMIP的约束写作尽量整段相加不要逐个变量append否则在循环里会越来越慢。如果用了sdpvar矩阵约束写法比如sum(P,1) Load会比for循环快很多。5.3 边界情形与敏感性分析模型建好后建议做几组敏感性分析验证稳健性。我通常改变三组参数新能源渗透率、燃料价格、备用容量比例看调峰成本如何变化。新能源渗透率从10%升到40%时调峰成本会随之上升但上升速率不是线性的。20%以下时成本增量不大超过30%后净负荷波动加剧启停次数和深度调峰小时数明显增加成本急剧上升。这个非线性关系很有价值写论文时可以作为政策性结论。燃料价格影响的是调峰成本的绝对数额但不影响分摊比例因为分摊比例只跟场站波动特征有关。备用容量比例的影响则要复杂一些它既影响总调峰成本基数也影响系统对新能源波动的响应能力。这些分析不需要额外写很多代码只需要把求解过程包装成一个函数然后循环调用即可。用parfor并行循环可以显著减少敏感性分析的时间。6. 个人经验与后续扩展建议6.1 关于调峰成本量化与分摊我的几个核心体会做完这个项目我最大的感受是模型的技术难度远低于问题定义的难度。把成本账算清楚、把分摊规则设计得让各方信服才是最耗精力的部分。技术上用Matlab加YALMIP加Gurobi的组合已经足够真正需要花时间的是数据清洗、场景设计和结果解读。另外成本量化不能只停留在数学表达要跟实际运行数据对得上。我建议拿到真实的风光出力数据和机组运行数据后用一年的8760小时数据做短期滚动模拟看看模型能否复现历史上的机组启停和深度调峰频次。如果模拟结果与历史运行数据偏差很大先不要急着调参而是要回到方法层面检查基准场景的设定是否合理。6.2 这个模型还能往哪些方向扩展我目前这个版本还是集中式框架下的确定性模型后续有不少扩展空间。一是引入源荷不确定性用随机规划或鲁棒优化来替代确定性模型这样得到的调峰成本会包含风险成本更贴近真实运行。二是把需求侧响应资源纳入调峰资源池让用户侧参与分摊与调峰分摊模型也要相应扩展。三是与电力市场出清模型结合将调峰成本作为辅助服务费用通过市场机制自动分摊。如果想往深度做可以考虑把现在的单层优化扩展为双层优化模型上层是调峰成本分摊决策下层是各场站的响应行为用于研究分摊规则对投资行为的激励影响。代码结构上需要在现在的模型外套一层迭代循环每次迭代更新分摊比例再回到下层优化求解直到收敛。这套模型现在放在一个有可再生能源并网仿真需求的教研项目里后续可以直接对接生产模拟软件的数据格式。如果大家在实际复现过程中遇到问题欢迎在评论区和我交流具体算例我可以针对某个细节再出一篇更详细的案例拆解。