ARTICLE DETAIL

资讯详情

深耕网站视觉设计与运营推广的一线实战洞察。

考虑源荷两侧不确定性的含风电电力系统低碳调度Matlab实现

考虑源荷两侧不确定性的含风电电力系统低碳调度Matlab实现 做电力系统调度优化这几年类似的题目几乎每个学期都会在我这边出现一次“考虑源荷两侧不确定性的含风电电力系统低碳调度Matlab代码实现”。如果你也正在做这类研究大概率是卡在这几个地方不确定性怎么建模才不算拍脑袋、低碳目标怎么进目标函数、Matlab代码搭到什么程度才算真的跑通。这篇文章就来把这些事一件件拆开讲围绕风电、负荷双侧预测误差给出一套可以用课程设计、论文复现和个人项目练习的调度建模与求解框架。适合正在做电力系统优化方向的学生也适合想从确定性调度转向不确定性调度的从业者。我默认你已经会基本Matlab和优化求解器但就算你只有一点基础按下面的顺序走也能跑出第一版结果。这个选题的核心价值不在于“代码文件名有多漂亮”而在于你能不能回答三个问题不确定集或场景怎么生成、碳排放成本怎么量化、调度结果如何在成本和低碳之间取得平衡。把这三点打通剩下的就是搭模型和调参的过程。1. 场景与调度思路为什么要把“不确定性”和“低碳”放在一起1.1 风电接入之后调度为什么变难了早期电力系统调度最怕的两个字叫“预测”。好在负荷预测误差相对较小调度员只要留出旋转备用基本就能保安全。但是风电大规模接入后这个平衡被打破了。风机出力由自然风速决定且存在明显的反调峰特性夜晚负荷低谷时风速往往偏高白天负荷高峰时风速往往偏低。这个“反着来”的特性直接导致原有的确定性调度思路不再适用。更麻烦的是风电预测的误差通常比负荷预测误差大一个量级。风速稍变风功率可能从50%出力掉到20%出力。如果你只按预测值的单点情况安排机组计划实际运行时就会面临两大类问题要么出力不足需要紧急开启高成本机组或者切负荷要么出力过剩被迫弃风。任何一类都意味着经济性和安全性同时受损。所以现在的主流做法是把风电出力和负荷水平都看成带概率分布的随机量而不是固定的一组数。调度计划需要在不确定性进来之前就做出来还要保证在所有“可能的世界”里都尽量不越界、不亏电、不浪费。这就是“考虑源荷两侧不确定性”这句话背后的真实工程需求。1.2 源荷两侧不确定性拆开来看到底是什么“源侧不确定性”主要指风电出力预测误差也可以扩展到光伏出力或水电来水波动但本题里关注点就是风电。风电预测误差本质上来源于数值天气预报的不准确所以模型里很有代表性的处理方式是先预测风速再转换成功率并给预测功率附上一个误差分布。这个分布可以用正态分布近似也可以根据历史数据拟合出更贴合实际的偏态分布。“荷侧不确定性”指负荷预测误差主要受天气、产业结构、用户行为等因素影响。在区域电网尺度上负荷预测误差通常服从平均值为零的正态分布标准差大约为预测负荷的1%~3%。这部分误差单独看不严重但当荷侧误差和风电误差同时出现时会在某些时段形成双向叠加极大地压迫系统可调度空间。这里必须记住一个关键点不能把源和荷两侧不确定性分开做两次独立备用因为二者的偏差可能正相关、负相关或完全不相关。更稳妥的做法是把二者作为独立随机变量同时抽样生成联合场景才能真正反映最恶劣情形。这也是很多毕业设计里只搞了个风电场景、却把负荷当成固定值拍进去最后结果显得很“假”的原因。1.3 低碳调度到底改变了什么传统经济调度只看发电成本目标是让火电机组经济运行。但含风电的低碳调度目标函数里多了一块“碳排放量”或“碳排放成本”。在双碳目标大背景下碳排放不再只是环保报告里的一个数字而是可以直接折算成成本的约束条件。低碳调度一般有三种落地方式。第一种最简单把碳排放量作为软目标加入目标函数用价格系数折算成成本。第二种是设置碳配额系统碳排超出配额时需要用碳交易市场购买额度购买成本进入目标函数。第三种更严格把碳排放作为硬约束限制调度周期内的总排放上限。实际论文和工程项目里最常见的是前两种的结合目标函数里含碳交易成本同时保留排放上限约束。风电的低碳价值在这个模型里非常直接风电机组几乎零碳排放在有风电接入的情况下系统可以通过调整火电出力来减少总碳排从而少买碳排放配额。这部分“碳减排收益”如果能在目标函数中显式体现低碳调度就不再只是口号而是一个可以被优化算法自动权衡的经济信号。2. 不确定性建模与场景生成这是调度计算的地基2.1 风电功率的不确定性建模风电功率不是一个可以直接用正态分布描述的物理量因为它由风速经过三次方关系转换而来。比较经典的流程是先用Weibull分布描述风速的随机性再通过风机的功率曲线转换得到功率场景。式中Weibull分布的形状参数和尺度参数需要根据当地风场历史风速拟合如果没数据取形状参数k等于2左右、尺度参数c按平均风速换算也经常能搞出一版可用结果。如果你手头的数据是历史风功率不走风速曲线这条路也可以直接对预测误差建模。比如将实际风功率视为“预测值误差”误差项用均值为零的截断正态分布描述并限制在风电场装机容量上。这种方法实践起来更省事也更贴近调度系统里“预测—修正—再计划”的实际运行逻辑。我个人在做Matlab代码时习惯双轨验证先按风速Weibull分布生成一组样本再按预测误差正态分布生成一组样本两者交叉检验。原因很简单——如果只用误差模型结果会偏向“预测值附近抖动”缺少对极端风速的覆盖如果只看风速分布又可能忽略预测系统本身偏差带来的持续性影响。2.2 负荷预测误差建模与双侧场景构造负荷预测误差相对成熟普遍假设为均值为零的正态分布标准差取预测负荷的1%~3%。在建模时可写为[ P_L^s P_L^{forecast} \varepsilon_L^s, \quad \varepsilon_L^s \sim N(0, \sigma_L^2) ]其中负荷场景的数量要与风电场景保持一致这样才能配对成联合时序场景。生成联合场景时建议先分别生成每个时段的风电功率和负荷样本再把同一时段的样本配成一对。这样做的好处是调度模型可以识别同一时刻源荷偏差的真实叠加而不是让每个不确定量各自独立演进。在实际代码里很多人会直接把负荷预测值当成固定数据只在风功率上加扰动。这样程序确实更快但不是严谨的“源荷双侧不确定性”。如果审稿人或答辩老师看到你的模型里负荷全是单点大概率会直接点出问题。既然题目已经明确写了“源荷两侧”至少要让负荷也带上误差带哪怕只用最基础的正态分布场景整个模型的完整度也会立刻上一个档次。2.3 场景生成之后必须做的事场景削减蒙特卡洛抽样能轻松生成几千个场景但你不可能把几千个场景全丢进优化模型里。一是变量规模爆炸求解时间不可接受二是许多场景之间相似度极高把它们一起放进模型只会增加约束却不会增加信息含量。因此需要做场景削减从原始场景集中挑出有代表性的少量场景代表整个概率空间。常用方法有概率距离聚类法K-means、快速前向选择法和启发式后向削减法。按我的使用习惯基于K-means聚类的方式性价比最高先随机生成1000个原始场景然后聚类成10~20个典型场景每个场景保留其聚类中心并统计该类样本占比作为概率。这样既覆盖代表性波动又控制模型规模。如果你用的是YALMIP场景数量建议控制在10~20个之间。低于5个不确定性描述会失真高于30个求解时间会明显拉长尤其在考虑机组启停时。这个数量不是越高越好而是要让目标价值随场景数增加趋于稳定且可解释。2.4 场景法的局限性和鲁棒思路补充场景法本质是“用部分代表全域”所以它无法保证覆盖所有极端情况。一个更稳健的选择是引入鲁棒优化不指定每个随机量的精确概率分布只定义不确定集比如盒式不确定集或椭球不确定集寻找在最坏情况下仍然可行的调度方案。但鲁棒优化也有自己的问题就是结果偏保守经济性差。折中的方案是分布鲁棒优化用矩信息约束不确定性分布集合既比场景法更稳健又比纯鲁棒更经济。这个方向稍深一些不建议零基础直接上。如果你做的题目是课程设计或普通期刊论文场景法完全够用且更容易在答辩时解释“场景是怎么来的、概率是多少”。我个人在写含水火的调度项目时会把场景法作为基准方案罗列出各场景下的出力细节然后追加一个“极端场景”或“最坏负荷/风电组合场景”来验证模型韧性。这样一个基准案加一个压力测试结论说服力会强很多。3. 低碳经济调度模型从目标函数到约束条件3.1 目标函数运行成本与碳排放如何加权含风电的低碳调度目标函数至少包含两大部分常规机组运行成本和碳排放相关成本。常规机组运行成本可用二次函数表示即每台火电机组出力对应的煤耗成本。风电成本通常取一个很小的运行维护系数甚至简化为零但弃风惩罚成本不能没有否则风功率会被无低成本地完全消纳这在工程上不真实。碳排放成本可以有两种写法。第一种是简单的碳税式成本单位碳排放乘以碳价第二种是更接近电力现货市场的配额交易式即系统总排放量减去免费配额后的差额乘以碳交易价格。后者更符合国内碳市场的设计逻辑也能更好地展示风电的减排价值所以稳妥起见我建议用配额交易模型。于是目标函数可以写为[ \min \quad \sum_{t} \sum_{i} \big[ C_i(P_{i,t}) C_{CO2} \cdot (E_i(P_{i,t}) - A_i) \big] C_{wind} \cdot P_{wind,t} C_{curtail} \cdot P_{curtail,t} ]如果你考虑两阶段随机调度目标函数里还会多一项“各个场景下的期望调整成本”包括火电机组增减出力成本、弃风惩罚和失负荷惩罚。这一项是场景法建模的灵魂它让模型能提前为“未来可能发生的偏差”预留可调节空间。3.2 系统约束功率平衡、出力区间、爬坡与旋转备用调度模型跑不跑得通约束的完整性比目标函数更关键。最基础的四个约束必须写清楚功率平衡约束任意时刻常规机组出力加上风电出力等于负荷需求加上网络损耗如果计及弃风和切负荷还要把这两个松弛变量放入平衡方程。机组出力上下限约束每台火电机组出力不能超过其技术最小出力和最大出力。机组爬坡约束相邻时段之间机组出力变化量不能超过最大爬坡速率。这是风电大波动场景下的关键约束很多论文复现者忘了它结果调度结果里机组出力“跳变”一看就不符合实际。系统旋转备用约束由于风电和负荷存在预测误差系统必须具备上调和下调备用容量。备用约束在整个模型中承担“安全兜底”的角色不能省略。如果在随机规划框架下功率平衡和爬坡约束还应当分“日前计划”和“实时调整”两层。第一阶段定机组基准出力第二阶段允许机组在各场景下做小范围增减但调整量受爬坡和剩余容量限制。这么一拆模型才真正具备“面对不确定性仍能调整”的能力。3.3 碳排放约束与碳交易机制的具体写法碳交易机制在调度模型中通常拆成三步。第一步计算每台火电机组的碳排放量一般用出力的一次或二次函数表示单位是tCO2/MWh第二步给定系统免费碳排放配额这个配额通常按历史排放水平或机组类型设定第三步计算总排放量减去总配额差值进入碳交易市场。若为正则买碳若为负则可出售碳配额获得收益。我建议在Matlab代码中把碳配额设置为一个可调参数而非固定常数。这样做的好处是你可以快速测试不同配额水平对调度结果的影响。比如把配额调低就会看到风电消纳量上升、火电出力下降这是非常有说服力的敏感性分析图表。硬性的总排放量上限也可以做进约束里作为碳交易成本之外的第二道闸门。逻辑很简单如果碳交易价格太低目标函数可能为了省钱而多排碳此时硬约束就能防止碳排突破红线。实际实现时两条腿走路最稳。3.4 为什么说这种调度可以体现“低碳”简单算一笔账假设一台100MW火电的碳排放强度约为0.8tCO2/MWh一台50MW风电场在相同时段出力30MW这部分出力替代火电后每小时直接减少约24吨碳排放。如果碳市场价格为50元/吨则每小时减排收益约1200元。这个数字放在日调度里就是一天接近三万元的经济信号。低碳调度模型的本质就是把这类减排信号从“感觉上应该做”变成“优化器自动算出来应该做”。风电场不出力的时候火电承担基荷碳排自然高风电场出力充足时火电主动压低出力甚至保留更多负备用空间吸纳风电。这个行为不是靠人工指令而是靠碳价格传导进目标函数后由优化自动寻优得到的结果。所以低碳调度和传统经济调度最大的差别就在于传统调度中风电只是替代火电的免费礼物而低碳调度中风电是一个能够减少碳配额支出并获得经济收益的主动资源。这一点想在论文里讲清楚直接画一张“碳价升高时风电消纳量上升”的敏感性图就够了。4. Matlab实现要点从建模到求解器配置4.1 总体代码架构设计我建议把整个Matlab工程按数据、场景生成、模型构建、求解、后处理分模块组织不要把所有东西塞进一个脚本里。工程结构大致如下wind_lowcarbon_dispatch/ |-- data/ % 负荷、风电预测曲线、机组参数 |-- scenario/ % 场景生成与削减 |-- model/ % YALMIP建模主函数 |-- solve/ % 求解器配置与优化执行 |-- plot/ % 结果可视化 |-- main.m % 主程序入口这个结构的价值在于你不必为了改一个机组参数而把整段代码翻一遍。模块化还有一个好处就是方便做多方案对比。比如只改碳配额跑的仍然是同一套模型函数自然就能画出配额变化对结果影响的曲线。主程序无非就是三步读数据、生成场景、调用模型求解。写代码时优先保证能跑通再考虑优化运行时间。不要一上来就套花哨的加速技巧否则代码报错时你根本不知道是建模问题还是加速逻辑问题。4.2 YALMIP建模核心代码示例我用YALMIP实现两阶段随机低碳调度模型的简化版。核心大致如下% 参数初始化已省略ngen, Nt, Ns, Pmax, Pmin, ramp, ... % 场景输入: Pwind_s(Nt, Ns), Pload_s(Nt, Ns), prob_s(1, Ns) P sdpvar(ngen, Nt, full); % 第一阶段日前出力计划 r_up sdpvar(ngen, Nt, full); % 上调备用容量 r_down sdpvar(ngen, Nt, full); % 下调备用容量 % 第二阶段场景调整量 deltaP sdpvar(ngen, Nt, Ns, full); curtail sdpvar(Nt, Ns, full); % 弃风量 shed sdpvar(Nt, Ns, full); % 切负荷量 Constraints []; % 第一阶段约束 for t 1:Nt Constraints [Constraints, sum(P(:,t)) sum(Pwind_forecast(:,t)) Pload_forecast(:,t)]; Constraints [Constraints, Pmin P(:,t) Pmax]; if t 1 Constraints [Constraints, -ramp P(:,t) - P(:,t-1) ramp]; end end第二阶段约束可写成循环场景内的再调度平衡公式这里最关键的是每台机组的调整量与其备用的关系for t 1:Nt for s 1:Ns Constraints [Constraints, deltaP(:,t,s) r_up(:,t)]; Constraints [Constraints, deltaP(:,t,s) -r_down(:,t)]; Constraints [Constraints, Pmin P(:,t) deltaP(:,t,s) Pmax]; end end目标函数里除了发电和碳成本再按场景期望加权加入调整补偿、弃风和切负荷惩罚最后调用optimize求解Objective base_cost co2_cost sum(prob_s .* expected_adjust_cost); ops sdpsettings(solver, gurobi, verbose, 2); [diagnostic, solution] optimize(Constraints, Objective, ops);这只是一个小骨架真正落地还需要把时段数、场景数搭好尤其注意deltaP这个三维变量的索引方向。我见过很多次报错就是因为sdpvar的维度顺序和循环下标不一致。4.3 求解器选择与参数设置Matlab下求解混合整数线性规划或二次规划第一选择是Gurobi或CPLEX。如果学校没有商业求解器授权可以用YALMIP自带的sedumi或sdpt3处理连续问题但遇到整数变量就会吃力。更轻量的替代方案是免费的SCIP或HiGHS但要在Matlab里接入会稍微折腾。调求解器参数也是关键。建议优先设置两个参数一个是TimeLimit另一个是MIPGap。对普通课程设计MIPGap设置在1%到5%之间就足够硬怼到0.1%会把求解时间拉得非常长。我的习惯是先用3%的gap快速出一版结果观察变量分布有没有明显不合常理的数值再收紧到1%跑最终版本。如果模型里没有整数变量只是一个线性规划或二次规划Gurobi通常几十秒内就能解决。但只要你加入了机组启停变量问题就变成混合整数规划场景数稍微一多就会指数级增长。所以想控制求解时间最有效的办法不是买更贵的机器而是削减场景数和机组数。4.4 结果输出与可视化别把图只画给自己看调度结果的输出不能只看目标函数值。至少应该画三张图第一张是各时段机组出力堆叠图含风电出力曲线第二张是各场景下的平衡偏差即负荷需求与发电出力的差值观察是否有系统性缺口第三张是碳排放量随碳配额或碳价变化的敏感度曲线。堆叠图要能清楚的看出“风电大发时段火电出力被压下来”的效果如果任意时段出现风电出力大幅超出系统消纳能力堆叠图会表现出弃风或减出力这往往是约束设计是否合理的信号。在论文或报告中强烈建议加上“无碳约束、含碳价、含碳配额碳交易”三个方案的结果对比。三个点一对比读者一眼就能看到低碳约束如何改变调度决策比你写几段文字都管用。后处理代码尽量用stackedbar或area不然图会一眼难尽。5. 调试实录那些年踩过的坑5.1 场景数到底取多少合适我第一版代码用的是5个场景求解飞快但风电出力偏差窄得离谱系统备用需求被严重低估改成50个场景后结果更稳定了但求解时间翻了十倍不止。后来用快速前向场景削减从2000个原始样本里聚出15个场景再结合概率权重来替代等概率场景效果立刻变好。如果你不确定自己的场景数是否合理做一次收敛性测试分别用5、10、20、30个场景跑同一组参数画出目标函数值随场景数变化的曲线。当目标值在某个数量之后不再明显变化时就说明这个场景数已经足够。别小看这个测试它在答辩时几乎等同于一个方法验证环节。5.2 求解无解或一直超时无解不是罕见的问题。常见的无解原因有三个一是功率平衡约束和负荷、风电场景不匹配比如忘了在平衡方程里加弃风和切负荷变量二是爬坡约束过严机组从一个出力水平跃变到另一个出力水平超过了限值三是备用约束写死之后系统没有足够容量支撑最恶劣场景。排查时先检查模型的可解性。把目标函数改成常数也就是只求可行性如果仍然无解说明约束本身不成立。接着按变量逐一宽松先放开最恶劣场景再放开备用容量最后放开爬坡约束看问题出在哪一层。这个方法我试过无数次每次都能快速定位到具体约束。5.3 低碳约束过紧导致结果失真碳配额设得太低时模型会进入一个很尴尬的境地为了不超碳排火电只能压到最小出力但如果负荷高峰远超风电最小火电出力之和模型就必须大量切负荷。此时目标函数里虽然碳排达标系统却牺牲了可靠性。这种结果看着像低碳了实际上是伪低碳不值得表扬。保障可靠性的办法是给失负荷加高额惩罚成本同时在结果分析里单独列出“失负荷电量”指标。如果失负荷超过总负荷的某一比例说明碳约束过于激进需要回退配额或者增加储能/联络线等灵活性资源而不是让模型硬冲。5.4 实用避坑清单速查问题现象常见原因处理办法目标函数值太大且不稳定场景概率未归一化检查prob_s求和是否为1风电曲线没有引起火电变化模型中风电成本设为零且无消纳约束加入弃风惩罚或风电最小消纳比例优化结果出现机组跳变缺少爬坡约束在日前计划中加入爬坡限制碳排始终等于配额上限碳配额约束过紧或目标函数未加碳价调整配额或检查碳交易成本公式求解特别慢场景数过多或含整数启停变量做场景削减设置合理MIPGap结果图很难看出低碳效果没有做方案对比至少跑出无碳价/有碳价两版结果这个表查起来很方便基本覆盖了大多数复现时容易遇到的坑。调试过程中保持一个习惯每次只改动一个变量翻看结果变化而不是把参数一口气全改掉。这样就算出问题你也能知道是谁导致的。6. 从“能跑”到“能讲”一些个人体会代码能跑通只是第一步能把结果讲明白才是另一道坎。我见过太多人拿着一个算例结果面对“为什么在这个时段弃风”这类问题时说不清楚。根子在于他们用的模型都没有把弃风成本写成显式变量也没有按场景统计弃风时段分布当然无从解释。我的建议是哪怕导师没有要求也把弃风电量、碳排放总量、供电可靠性三个指标单独做统计。不要只输出目标值。三个指标列一列风电的正面作用和系统的紧张程度都一目了然。答辩或汇报时这些数字就是你的论据。实际做项目时还有一个体会就是碳价对调度结果的真实影响区间往往不像你想象得那么大。碳价从30元/吨改到80元/吨碳排总量可能只降几个百分点除非你同时把配额也收紧。所以低碳调度不能只靠碳价调节还是要配合同步提高风电消纳能力、增加备用资源和灵活调节能力这个组合拳才是工程落地最有效的路径。如果你后续想扩展比较推荐往“分布鲁棒优化低碳调度”方向走把风电出力的矩信息放进调度模型或者把储能系统也纳入作为灵活性资源。前者偏理论后者更偏工程。两者都能让现在这套Matlab代码变得更完整、更有说法力。跑通当前模型之后在这些方向上迭代下去会很快进入能独立做方案的状态。
返回列表