ARTICLE DETAIL

资讯详情

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

高比例可再生能源系统调峰成本量化与分摊的Matlab实现

高比例可再生能源系统调峰成本量化与分摊的Matlab实现 最近在做一个高比例可再生能源电力系统的调峰成本量化与分摊分析项目把Matlab代码实现过程完整整理了出来。这个课题很现实风电、光伏装机占比一高系统净负荷的峰谷差就会急剧拉大火电机组被迫频繁深度调峰甚至启停调峰调峰成本不再是理论概念而是实打实要算清楚、分明白的账。本篇分享我的建模思路、关键公式、核心代码片段和实测数据适合正在做电力系统经济调度、辅助服务市场设计或者新能源并网影响评估的工程师和研究生参考。高比例可再生能源系统面临的调峰压力本质上不是“电量不够”而是“调节能力不够”。很多人把注意力放在弃风弃光率上忽略了调峰成本量化与分摊其实后者才是市场机制能不能落地的关键。我在这个项目中用Matlab实现了从成本建模、场景仿真到分摊计算的全流程代码结构清晰后续也方便改成生产版本。1. 高比例可再生能源系统的调峰压力与成本构成1.1 净负荷曲线“鸭子化”带来的调节需求先看一个最基本的物理场景。传统电力系统里负荷曲线是系统调度的首要输入火电机组跟着负荷走。但可再生能源大规模接入后调度面对的不再是负荷曲线而是净负荷曲线[ P_{\text{net}}(t) P_{\text{load}}(t) - P_{\text{wind}}(t) - P_{\text{solar}}(t) ]风电在夜间出力大光伏在中午出力大而负荷的高峰通常出现在白天和晚间区域电网里就常出现中午净负荷塌陷、傍晚净负荷陡升的“鸭子曲线”。我们做典型日数据测算时净负荷峰谷差比单纯负荷峰谷差拉大了30%50%个别日甚至翻倍。系统要维持安全运行必须让火电机组不断调整出力最低技术出力以下的调节就属于深度调峰。调峰需求不是固定的它随新能源渗透率、负荷特性、开机方式变化。量化调峰成本第一步就是把这种调节行为拆解到每一个机组、每一段时段上否则后面分摊无从谈起。1.2 调峰成本不只是多烧煤我在和不少同行交流时发现大家对调峰成本的理解不一样。有的人只看煤耗增量有的人只看启停费用都不全面。从实际调度看调峰成本至少包含四部分。常规调峰煤耗成本机组在50%100%出力区间内调峰煤耗率随出力降低而升高单位发电成本上升。深度调峰附加成本机组出力低于50%后需要投油助燃、稳燃改造或者承担更高的设备磨损和检修频率。这部分成本不是线性增长而是跳跃式上升。启停调峰成本当深度调峰仍无法满足平衡时机组需要启停。启停一次的费用包含锅炉点火燃料、辅助设备损耗、热应力造成的寿命折损。可再生能源弃电机会成本为了给火电让出调峰空间调度可能被迫弃风弃光。损失的电量价值就是调峰的隐性成本。后面我在Matlab里就是按照这四块分别建模最后累加得到系统总调峰成本。这样做的好处是每个成本项对应明确的物理含义分摊时也能找到对应的责任主体。2. 调峰成本量化的核心建模思路2.1 火电机组分段运行成本曲线火电调峰成本建模不能用一个简单的二次函数写完因为深度调峰阶段的成本特性发生了改变。我采用的是分段线性化方法把机组出力范围分成正常运行区、深度调峰区、启停调峰区三段每段用不同的成本函数。正常运行区出力在50%100%[ C_{\text{norm}}(P) a_1 P b_1 ]深度调峰区出力在30%50%[ C_{\text{deep}}(P) a_2 P b_2 K_{\text{low}} ]其中(K_{\text{low}})是深度调峰附加成本投油或寿命损耗可以表示为一个常数项或者随深度增加的函数。为了线性规划求解方便我通常把(K_{\text{low}})处理成固定成本当机组进入深度调峰区时激活动作。在Matlab里我预先计算机组在每个出力水平的单位成本曲线用addpiece思路或者interp1做插值。实际代码中我用的是离散化将机组出力离散成若干个运行点每个运行点对应一个成本值这样后续用线性规划时不需要重新线性化。机组参数表结构清晰包含额定容量、最小出力、煤耗系数、投油运行成本、启停费用。成本计算函数calcUnitCost(unit, P)返回该机组在出力P时的每时段运行成本。2.2 机组启停成本与最小运行/停机时间约束启停调峰虽然不常发生但单次成本很高。一个600MW的火电机组热态启动一次的费用动辄几十万元。在建模时我通常引入二进制变量(u_{i,t})表示机组i在t时刻是否运行(y_{i,t})表示是否在t时刻启动。启停成本如下[ C_{\text{su}} \sum_{i,t} SUC_i \cdot y_{i,t}, \quad C_{\text{sd}} \sum_{i,t} SDC_i \cdot z_{i,t} ]其中(z_{i,t})是停机变量。更严格的模型还需要最小连续运行时间和最小连续停机时间约束否则优化会通过频繁启停来“钻空子”。在机组组合问题中这些是标准约束但如果是仿真模式我可以预先给定一个启停计划避免求解混合整数规划的复杂度从而把精力集中在调峰成本计算上。2.3 弃风弃光的机会成本处理弃风弃光成本本质上是不产生实际支出、但损失潜在收益的机会成本。在Matlab仿真中我通过拉格朗日乘子或直接事后统计来处理。具体做法是在仿真中允许弃电记录每个时刻的弃电量最后乘以单位可再生能源收益参考上网电价得到弃电损失。这个值直接计入调峰总成本。计算时要小心弃风弃光不是均匀分布的往往集中在净负荷低谷时段。比如某天夜间风电出力大、负荷低火电机组已经全部压低到最小技术出力只能弃风。这种“被迫弃电”是系统调峰能力不足的表现所以把它归入调峰成本是合理的。为了避免重复计算我在代码里用一个标志变量判断弃电原因只有因为调峰能力不足导致的弃电才计入调峰成本。3. 调峰成本分摊模型的设计3.1 分摊问题的主体与原则成本算出来了下一步是分给谁、怎么分。高比例可再生能源系统里和调峰有关的主体主要有三类传统火电/水电提供了调峰服务理论上应该获得补偿而不是分摊成本。风电场和光伏电站其出力波动加剧了系统调峰需求是调峰成本的“引发者”。电力用户负荷曲线的峰谷差也是调峰需求的因素。实际做分摊时我们通常只对新增的可再生能源运营商进行分摊因为传统用户本来就承担辅助服务成本。分摊原则有三条谁引发谁承担按各主体对系统调峰需求增加的贡献来分摊。谁受益谁承担从“保障新能源消纳”中获益的主体应承担部分成本。可核算、可操作分摊方法要能基于公开数据计算不能太黑箱。3.2 基于净负荷峰谷差增量的“边际贡献分摊法”这是最直观、最容易在Matlab里实现的方法。逻辑是先算没有该新能源电站时系统的基准调峰成本再算加入该电站后的调峰成本差额就是这个电站引起的边际调峰成本。具体步骤如下定义基准场景只保留负荷曲线新能源出力设为0求出系统最小调峰成本(C_0)。评估整体场景负荷所有新能源求出系统总调峰成本(C_{\text{total}})。计算整体增量成本(\Delta C C_{\text{total}} - C_0)。对每个新能源电站j计算移除j后的系统调峰成本(C_{-j})则该电站在整体环境下的边际责任为(C_{\text{total}} - C_{-j})。归一化分摊每个电站分摊比例 (\frac{C_{\text{total}} - C_{-j}}{\sum_k (C_{\text{total}} - C_{-k})})。注意这种方法算出的边际贡献之和不一定等于总增量成本因为存在交互效应。我的处理是先归一化保证分摊比例总和为100%。3.3 基于Shapley值的合作博弈分摊方法如果希望理论无懈可击可以用Shapley值。它把每个新能源电站看成一个参与者把调峰成本当成合作博弈的特征函数。对于参与者集合N、参与者i的Shapley值计算公式是[ \phi_i(v) \sum_{S \subseteq N \setminus {i}} \frac{|S|! (|N|-|S|-1)!}{|N|!} \left[ v(S \cup {i}) - v(S) \right] ]其中(v(S))表示只有参与者集合S接入时的系统调峰成本。Shapley值满足有效性、对称性、可加性等公理理论公平性好。但实际使用时有个麻烦计算量随参与者数量指数增长。风电/光伏场站数量一多根本不可能穷举所有子集。我的做法是采用蒙特卡洛采样近似。在Matlab中随机采样大量子集顺序利用Shapley值的等价定义——随机排列下参与者i的边际贡献——来逼近精确值。实测中当参与者数量达到8个时采样1000次的结果与精确值误差控制在2%以内完全够用。4. Matlab实现细节与关键代码4.1 数据准备与场景生成我习惯用结构体数组存储机组数据用表格存储时序列数据。首先定义基础数据% 机组参数结构体 units(1).capacity 600; % MW units(1).Pmin 120; % 最小技术出力 units(1).a 0.00015; % 煤耗二次项 units(1).b 0.26; % 煤耗一次项 units(1).c 4.2; % 空载成本 units(1).deepCost 18000; % 深度调峰附加成本元/次 units(1).startCost 450000; % 启动费用元 units(1).minOn 4; % 最小运行小时 units(1).minOff 2; % 最小停机小时负荷和新能源出力用24小时曲线可以从Excel读入或者模拟生成。我编写了genScenario.m生成典型日数据包括负荷、风电、光伏的时序曲线并画出净负荷曲线检查峰谷差。load_curve [ ... 24个数值 ... ]; wind_curve [ ... 24个数值 ... ]; solar_curve [ ... 24个数值 ... ]; net_load load_curve - wind_curve - solar_curve;4.2 调峰成本计算函数实现核心函数calcPeakCost.m接收机组数据、启停计划、出力计划和弃电量返回总调峰成本及其分项。function [totalCost, costBreakdown] calcPeakCost(units, schedule, Pgen, Pcurtail) % schedule为各时刻机组启停状态矩阵Pgen为各时刻机组出力矩阵 % Pcurtail为各时刻弃电量向量 % 返回值包含燃料成本、深度调峰成本、启停成本、弃电机会成本 T size(Pgen, 1); nUnit length(units); fuelCost 0; deepCost 0; startCost 0; for t 1:T for i 1:nUnit if schedule(t, i) 1 P Pgen(t, i); minP units(i).Pmin; % 判断是否深度调峰 if P 0.5 * units(i).capacity P minP deepCost deepCost units(i).deepCost; % 每次进入深度调峰记一次附加成本 end % 燃料成本按二次函数计算 fuelCost fuelCost units(i).a * P^2 units(i).b * P units(i).c; end end % 启停成本根据schedule变化计算 end curtailCost sum(Pcurtail) * 350; % 假设可再生能源度电收益350元/MWh totalCost fuelCost deepCost startCost curtailCost; costBreakdown [fuelCost, deepCost, startCost, curtailCost];注意这个函数做了简化深度调峰附加成本只在进入深度区间时计一次实际项目里更精确的应该按运行时长累积。不过对于成本量级估算这种简化已经足够而且代码更容易理解和扩展。4.3 分摊模型的求解流程分摊模型单独写成calcAllocation.m支持边际贡献法和Shapley值法。function alloc calcAllocation(baseCost, totalCost, costWithoutEach, method) % costWithoutEach为每个参与者移除后的系统调峰成本 % method marginal 或 shapley if strcmp(method, marginal) marginal totalCost - costWithoutEach; alloc marginal / sum(marginal) * (totalCost - baseCost); elseif strcmp(method, shapley) % 需要传入子集成本矩阵这里示意主流程 end endShapley值计算为了保证效率我写成独立函数shapleyApprox.m基于排列采样。核心代码只有二十几行每次随机生成一个参与者排列然后顺序计算边际贡献累加起来再除以采样次数。4.4 结果可视化与导出为了让结果能直接用到报告里我做了几个可视化plot净负荷曲线和机组出力堆积图。bar各新能源场站的调峰成本分摊结果。用writetable把结果导出到Excel。figure; bar(allocResult); set(gca, XTickLabel, {风电场A,风电场B,光伏电站A,光伏电站B}); ylabel(分摊调峰成本万元); title(不同方法下的调峰成本分摊结果);可视化的意义不仅是展示更是检查模型行为是否合理。比如某风电场负分摊说明它接入后反而平抑了系统调峰压力这种情况在分布式储能场景可能出现需要人工复核。5. 算例测试与结果解读5.1 典型日场景设置为了验证模型我构造了一个小型系统算例3台火电机组容量分别为600MW、300MW、300MW2个风电场2个光伏电站负荷峰值3000MW风电装机800MW光伏装机500MW。所有数据设成典型夏季日过程风电夜间大、白天小光伏中午大、早晚小负荷呈早晚双峰。机组参数如下示例数据机组容量(MW)最小出力(MW)启停费用(万元)深度调峰附加成本(万元/次)G1600120451.8G230075281.2G330075281.2这个系统规模不大但足够演示建模和分摊逻辑。如果想测试更复杂的场景只需要扩充机组数量和市场参数。5.2 成本量化结果运行后典型日系统总调峰成本约为286万元其中燃料成本192万元占67%主要是机组在低负荷运行时单位煤耗升高。深度调峰附加成本38万元占13%共发生22次深度调峰事件。启停成本31万元占11%有两台机组各启停一次。弃电机会成本25万元占9%弃风电量约715MWh。从时序结果看成本高发的时段集中在夜间风电高峰期和傍晚负荷陡升期。夜间火电被压低到最小出力但风电仍有余量只能弃风傍晚光伏退出、负荷攀升需要机组快速爬坡甚至启动一台备用机组。这两个时段正好对应了调峰成本的两个峰值。5.3 分摊结果合理性分析我用边际贡献法和Shapley值法分别计算分摊结果并做了对比。场站边际贡献法分摊(万元)Shapley值法分摊(万元)差额风电场A92857风电场B7882-4光伏电站A5459-5光伏电站B46451可以看到两种方法结果接近但趋势略有不同。边际贡献法更突出风电场A的责任因为该风电场在夜间出力波动最剧烈独立作用时对系统净负荷峰谷差增量最大。Shapley值法考虑到了场站间的交互效应当风电场A和光伏电站B同时接入时它们的出力曲线互补实际总调峰成本增量小于各自单独接入时之和所以分摊量被重新平衡。这类差异在市场设计时很关键。如果采用边际贡献法风电场A可能认为不公而抵制Shapley值法理论更公平但计算复杂需要给参与者解释清楚。我在实际方案里建议先用Shapley值做参考再结合政策目标进行调整。6. 实际项目中的注意事项与避坑建议6.1 数据单位与量纲统一这是新手最容易翻车的地方。负荷数据可能是MW新能源出力可能是MWh成本参数可能是元/万kWh时间步长可能是15分钟或1小时。我在代码开头强制统一所有单位功率用MW能量用MWh成本用万元时间步长为1小时。换算方法很简单——只要记住能耗 功率 × 时间成本 能耗 × 单价。比如某个弃电量是500MWh度电收益是0.35元/kWh对应机会成本就是500 × 1000 × 0.35 175000元 17.5万元。单位一混乱最后结果差出几个数量级排查起来非常痛苦。6.2 求解器选择与计算规模控制如果调峰成本模型嵌入到机组组合优化里就涉及求解大规模混合整数线性规划。Matlab自带intlinprog对小规模问题能用但遇到几十台机组、96个时段的问题求解速度会变得很慢。我项目的实际经验是当机组数超过20台、时段超过24个时最好用YalmipGurobi/Cplex的组合建模更灵活求解效率高很多。如果不想引入额外求解器可以采用启发式方法先按等微增率分配出力再判断是否越限虽然不一定全局最优但算调峰成本量级足够。我的项目前期就是用这种方法快速估算后期才用混合整数规划精算。6.3 分摊结果的稳定性和公平性修正Shapley值结果虽然理论公平但可能不稳定。因为当参与者出力曲线高度相关时子集成本函数的凸性假设可能不成立导致某些参与者分摊结果为负。负分摊在理论上合法表示该参与者实际减少了系统成本但市场机制里很难执行。我的处理办法在分摊结果中加入一个“调峰贡献修正系数”把负值拉平同时保证总和不变。具体做法是设原始分摊结果为(a_i)若存在负值将所有结果线性平移至非负。平移后再按比例调整保持总成本一致。记录修正量在上报结果时注明“已做公平性修正”。这个操作不是纯粹的数学题需要结合市场接受度。我在项目报告里会给出未修正和修正两个版本让决策者自己判断。6.4 别把“平均成本”直接当“边际成本”还有一类常见错误直接用系统总调峰成本除以新能源发电量得到“平均分摊成本”。这种做法在市场初期可以快速执行但会掩盖不同场站、不同时段的差异。比如一个夜间风电场和一个中午光伏电站对系统调峰的影响完全不同平均分摊会让夜间风电场少承担、让光伏电站多承担。高比例可再生能源系统的调峰成本分摊一定要基于边际贡献或博弈论方法才能提供正确的价格信号。最后再说一个实际教训调峰成本量化模型再精细也抵不过基础数据的质量。我最早用某州公开数据时发现新能源出力曲线和实际调度记录对不上后来才意识到时间坐标没有统一时区导致竞相调峰时段错位。现在我在处理任何数据前都会先把时间轴和单位制画出来检查一遍这个习惯帮我避免了很多浪费在Bug上的时间。希望这篇围绕调峰成本量化与分摊模型的Matlab实现梳理能给正在做同类课题的朋友提供一些可复用的思路和代码骨架。
返回列表