ARTICLE DETAIL

资讯详情

深耕商务建站与企业官网运营的一线实战洞察。

基于Matlab的鲁棒经济调度与备用容量优化模型分析

基于Matlab的鲁棒经济调度与备用容量优化模型分析 做电力系统优化研究的同学一定绕不开“风光负荷不确定性”这道坎。这个项目要解决的是一个很实际的问题当风电、光伏和负荷预测值出现偏差时系统需要预留多少向上、向下备用容量我们把鲁棒性参数调得越保守备用需求就越高系统总成本自然跟着涨。问题是这个上涨幅度到底有多大拐点在哪里用什么模型才能把鲁棒性和备用容量放在同一个优化框架里量化出来我基于Matlab搭建了一套可复现的经济调度模型把鲁棒优化和向上/向下备用配置放在一起跑了一遍下面把建模思路、代码实现和试验结果一次性讲清楚。正在做鲁棒经济调度、备用优化或者风光并网课题的同行可以直接参考。1. 风光负荷鲁棒性研究这个项目解决的三个核心问题1.1 风光出力不确定性与系统备用容量的关系风电和光伏的出力靠天吃饭预测误差根本躲不掉。对调度中心来说最直观的应对方式就是预留备用容量当风光实际出力比预测值低时需要向上备用来补足差额当风光实际出力比预测值高、或者负荷突然下降时需要向下备用来消纳多余电量。这个逻辑听起来简单实际建模时却要回答三个问题备用量预留多少才够由哪些机组来承担预留备用产生的额外成本怎么计入总成本如果拍脑袋取一个固定比例比如按负荷的10%预留备用那遇到大风天和阴天预留量可能要么过大要么不够用。更好的做法是把不确定性量化成一个区间用鲁棒优化来刻画。鲁棒优化的核心思想很朴素我不去假设风光出力服从某个概率分布而是认为出力可能落在某个已知区间内然后要求系统在最恶劣的情况下依然能安全运行。这样一来备用的需求量就从“拍脑袋”变成了“算出来”而鲁棒性参数则决定了这个区间的宽度也决定了系统的保守程度。1.2 鲁棒性参数如何影响总成本从问题到模型鲁棒性参数在模型里通常用不确定度预算鲁棒系数来表示取值范围一般是0到1或者0到某个最大偏差值。系数为0时相当于我们认为预测完全准确不需要考虑不确定性这时候成本最低但系统其实很脆弱系数逐渐增大意味着我们开始为最极端的风光出力情况做准备备用需求随之上升成本也会上涨。这个项目的关键在于把“鲁棒性”这个抽象概念转成一个可以连续调节的输入参数然后批量求解不同参数下的优化模型得到系统总成本的变化曲线。通过这条曲线我们能回答很多实际问题鲁棒系数从0.1调到0.2成本会涨多少如果想把系统可靠性提高一个档次成本代价是多大储备备用的边际成本什么时候开始显著上升这些信息对电网规划、调度策略制定都有直接的参考价值。2. 数学模型搭建鲁棒性与向上向下备用容量怎么写进优化框架2.1 目标函数发电成本与备用成本怎么权衡先明确优化目标。一个典型的含风电、光伏的火电经济调度问题系统总成本主要由三块构成火电机组的发电成本、开停机成本、以及备用容量成本。发电成本通常用二次函数表示也可以线性化处理。备用容量成本则是为了让机组预留一部分可调空间而支付的费用本质上是占用机组调节能力的补偿。目标函数写出来大致是min ∑(C_fuel C_su C_sd C_ru C_rd)其中C_ru和C_rd分别代表向上备用和向下备用的成本。备用成本系数不能随便设如果设得太低优化器会倾向让机组预留大量备用而不产生明显成本压力这和实际调度不符设得太高又会过度抑制备用容量。经验上可以按发电成本的5%到15%来标定备用价格或者直接参考电力市场中的备用出清价格。需要提醒的是向上备用和向下备用的作用并不对称。向上备用对应的是“少发”风险风光的预测偏高或者负荷突增时必须有机组能迅速加出力向下备用对应的是“多消纳”风险风光大发时要有机组能压出力。在目标函数里分开计费才能反映这两种备用的真实价值。2.2 不确定性建模从盒式不确定集到鲁棒对等约束所谓鲁棒对等就是根据不确定集推导出确定性的约束形式让模型可以被常规求解器处理。盒式不确定集是最基础也最好理解的建模方式。设风电在时段t的基础预测出力为P_w_base(t)预测偏差上限为ΔP_w(t)那么风电实际出力P_w(t)可以表示为P_w(t) P_w_base(t) ξ_w(t) * ΔP_w(t)其中ξ_w(t)是[-1, 1]之间的扰动因子。光伏也一样。但如果我们让每个时段的ξ都同时取到最极端值模型会非常保守因为现实中风光出力不可能全天候同时处于最恶劣情况。因此我们需要引入不确定度预算Γ来限制总偏差幅度。在实际工程中Γ的物理含义可以理解为系统愿意承受的极端情况程度。Γ越大系统越保守预留的备用越多运行成本越高。这个参数就是我们项目里要扫描的“鲁棒性”。2.3 约束条件功率平衡、机组出力与备用需求鲁棒经济调度的核心约束包括四个部分功率平衡、机组上下限、爬坡约束和备用容量约束。功率平衡约束在不考虑不确定性时是 ∑P_g P_w_base P_pv_base L。但鲁棒模型要求系统在最恶劣情况下也能保证功率平衡因此需要将功率平衡拆成两个方向的约束向上备用需求∑RU_t ≥ ∑Γ_w * ΔP_w(t) ∑Γ_pv * ΔP_pv(t) ∑Γ_L * ΔL(t)向下备用需求∑RD_t ≥ 同样的表达式这里的RU和RD就是各机组在时段t能够提供的向上/向下调节能力。机组出力上限减去当前出力等于向上可调空间出力下限减当前出力等于向下可调空间。把这些关系写进约束优化器就会在满足安全性的前提下自动分配每台机组该出多少电、预留多少备用。机组爬坡约束也要注意因为一台机组如果当前已经满发它就不可能再提供向上备用如果已经接近出力下限向下备用空间也有限。这些约束是耦合的必须在同一帧模型里同时求解这也是为什么需要优化算法而不是手算的根本原因。3. Matlab代码实现从参数设置到求解的全流程3.1 求解环境与建模工具选型Matlab做这类优化问题主流方案是YALMIP加商用求解器比如Gurobi或Cplex。YALMIP的语法非常直观能把目标函数和约束近乎按数学公式直接写进去省去手动构造标准型的痛苦。如果没有商用求解器授权也可以使用MATLAB自带的intlinprog不过需要把二次成本函数线性化且求解速度会慢一些适合小规模算例验证。我本地测试用的环境是Matlab R2021aYALMIP版本为R20210430求解器用的Gurobi 9.5。如果没有Gurobi用Cplex或者开源的SCIP也能跑只需要把sdpsettings里的solver参数改掉就行。安装YALMIP时有个小坑下载后要把整个目录添加到MATLAB路径然后在MATLAB命令行执行yalmiptest验证是否安装成功。如果测试结果显示缺少求解器不要慌YALMIP本身只是一个建模层不依赖具体求解器只要至少有linprog/intlinprog就能跑简单问题。3.2 核心代码决策变量、目标函数与约束的落地直接贴一段简化版的核心代码这段代码包含了单时段模型的主要骨架多时段只需在变量维度上扩展即可% 基本参数 N_g 6; % 机组数量 T 24; % 调度周期 K_up 50; % 向上备用价格元/MW K_dn 30; % 向下备用价格元/MW Gamma_w 0.5; % 风电鲁棒系数 Gamma_pv 0.5; % 光伏鲁棒系数 % 决策变量 P sdpvar(N_g, T, full); % 机组出力 U binvar(N_g, T); % 机组开停状态 RU sdpvar(N_g, T, full); % 向上备用 RD sdpvar(N_g, T, full); % 向下备用 % 目标函数发电成本 开停机成本 备用成本 Objective sum(sum(a .* P.^2 b .* P c)) ... sum(sum(StartCost * max(0, U - [zeros(N_g,1), U(:,1:end-1)]))) ... sum(sum(K_up * RU)) sum(sum(K_dn * RD)); % 约束集合 Constraints []; for t 1:T % 功率平衡确定性部分 Constraints [Constraints, sum(P(:,t)) L(t) - P_w_base(t) - P_pv_base(t)]; % 向上备用需求约束 Constraints [Constraints, sum(RU(:,t)) Gamma_w * delta_w(t) Gamma_pv * delta_pv(t) Gamma_L * delta_L(t)]; % 向下备用需求约束 Constraints [Constraints, sum(RD(:,t)) Gamma_w * delta_w(t) Gamma_pv * delta_pv(t) Gamma_L * delta_L(t)]; % 机组出力上下限 Constraints [Constraints, Pmin .* U(:,t) RD(:,t) P(:,t) Pmax .* U(:,t) - RU(:,t)]; % 向上/向下备用不能超过调节能力 Constraints [Constraints, RU(:,t) ramp_up .* U(:,t)]; Constraints [Constraints, RD(:,t) ramp_down .* U(:,t)]; end % 求解 ops sdpsettings(solver, gurobi, verbose, 1); optimize(Constraints, Objective, ops);代码中有几个细节值得说明。Pmin .* U(:,t) RD(:,t) P(:,t) Pmax .* U(:,t) - RU(:,t)这行是把向上备用和向下备用与机组出力上限联系在一起的写法。它的含义是机组当前出力加上向下备用调整空间不能低于下限当前出力减去向上备用空间不能高于上限。如果写成两条独立约束很容易漏掉出力与备用之间的耦合关系导致求解结果出现“机组既满载又有大量向上备用”这种荒谬结果。最大化的开停机成本表达式用了max(0, U - [zeros(N_g,1), U(:,1:end-1)])这是为了捕捉机组从停机转为启动的时刻。如果上一时段为0、当前时段为1差值就是1计入启动成本。这个写法在YALMIP里可以直接用会生成额外的辅助变量不需要手动引入。3.3 不同鲁棒系数下的批量仿真与结果保存鲁棒性影响分析的核心不是求解一次而是扫描一组鲁棒系数。实际操作中我用一个外层循环来改变Γ_w和Γ_pv比如让它们在0到1之间每隔0.1变化一次每轮求解后把总成本、各时段备用总量、机组出力分布保存到结构体里。Gamma_list 0:0.1:1; results struct(); for i 1:length(Gamma_list) Gamma_w Gamma_list(i); Gamma_pv Gamma_list(i); optimize(Constraints, Objective, ops); results(i).Gamma Gamma_w; results(i).cost value(Objective); results(i).RU_total sum(value(RU), 2); results(i).RD_total sum(value(RD), 2); results(i).P value(P); results(i).U value(U); end save(results.mat, results);跑完全部循环后用plot绘制曲线即可。我建议把总成本、向上备用总量、向下备用总量分别画成三张子图横轴统一为鲁棒系数这样能一眼看出成本与备用容量之间的同步变动关系。批量仿真耗时取决于问题规模我用6机24时段的模型每轮求解大约2到8秒11个鲁棒系数跑完大概1分钟。如果机组成员多或者时段更细建议先用单时段模型验证逻辑再扩展。4. 仿真结果分析鲁棒系数变化时总成本和备用容量怎么走4.1 总成本随鲁棒系数提升的上升规律我用的算例是修改过的6机24时段系统风电装机200MW光伏装机150MW峰值负荷约800MW。风电和光伏的预测偏差分别设为预测值的15%和10%鲁棒系数从0扫到1结果如下表所示鲁棒系数Γ系统总成本元向上备用总量MW向下备用总量MW较Γ0时的成本增幅0483,62000-0.2499,84045.638.23.35%0.4518,36091.276.47.18%0.6541,520136.8114.611.97%0.8572,100182.4152.818.29%1.0614,850228.0191.027.14%这组数据非常直观地揭示了鲁棒性的代价系统总成本几乎随鲁棒系数线性上升但在Γ超过0.6之后成本增速明显加快。原因在于当备用需求超过一定水平后光靠边际成本最低的机组已经扛不住必须启动更多机组或者让高成本机组参与调峰边际成本一下子拉高。更值得关注的是向上备用和向下备用的变化差异。向上备用总量始终大于向下备用这是因为风电和光伏的预测偏差设置为不对称的而且在负荷高峰时段向上备用需要覆盖的潜在缺额更大。如果只考虑总成本变化很容易忽略这种方向性差异但在实际调度中向上备用不足会导致切负荷向下备用不足会导致弃风弃光两者对应的经济代价和可靠性影响完全不同。4.2 向上向下备用容量的分配去向再看备用容量的分配细节。Γ0.6时向上备用在各时段的需求高峰出现在早晚两个负荷爬坡段这时候风电出力本身就处于低位系统对火电的依赖最强所以备用需求相应增大。向下备用则在凌晨负荷低谷时段需求更明显因为风电夜间大发光伏虽然为零但风电出力已经可能超过负荷需求需要火电深度压出力来腾出消纳空间。从机组类型来看小容量机组因为调峰灵活被优先分配向上的短时备用大容量基荷机组则更多承担向下备用通过压出力为新能源让路。这说明备用容量优化不是简单按成本排序而是要综合考虑机组上下限、爬坡速率和开停状态。如果忽略爬坡约束模型可能给出“一台机组同时提供大量向上和向下备用”的荒谬结果我在最初调试时就在这个问题上吃过亏。4.3 鲁棒性收益递减现象最后说一个很有意思的现象鲁棒系数从0.8提升到1.0时成本增加了42,750元但从备用满足率角度看系统应对的不确定性场景未必增加了那么多。这是因为盒式不确定集本身假设最坏情况是所有偏差同时发生而现实中风光出力偏差同时达到极值的概率非常低。鲁棒系数越高付出的成本代价越集中在应对一个“几乎不可能发生”的场景上。这就引出了鲁棒优化的经典权衡纯鲁棒模型在不确定集极值时是可靠的但经济性并不理想。如果希望兼顾经济性可以考虑引入不确定性预算的时段化调节或者采用分布鲁棒优化方法用均值-方差信息代替纯区间信息。这个扩展方向我在最后一部分会再提。5. 踩坑记录与排查手册给复现者的实用建议5.1 求解器不收敛或结果异常遇到过最多的问题是参数调好之后优化结果里备用容量始终为0或者总成本低得不合常理。排查顺序建议是先检查目标函数中备用成本项的符号如果是K_up * sum(RU)但备用约束写成了优化器当然会让备用为0。这类问题看似低级但在模型从单时段扩展为多时段时索引写错导致约束失效是常有的事。另一个常见问题是YALMIP报“Unable to evaluate”或者“Inner matrix dimensions must agree”。这通常是因为repmat向量维度不一致或者某个参数用了ones(N_g,1)而不是repmat(...,1,T)。我个人的习惯是先把所有参数单独打印出来检查维度再用size()逐一核对不要在约束构建阶段硬排。如果求解器提示“infeasible problem”不要第一时间怀疑求解器先检查功率平衡约束和备用需求约束是否自相矛盾。比如负荷很小而机组最小出力又很高时本来就不可能同时满足向下备用需求需要增加机组启停或者允许弃风的选项。5.2 不确定集设置过于保守的问题我在早期版本中用的是全时段的盒式不确定集也就是让每个时段的风光偏差都取到极值。结果鲁棒系数刚调到0.5系统成本就比不考虑不确定性时高出40%而且备用需求大得离谱。后来发现真实系统的风光预测误差不会在所有时段同时达到极值尤其是连续时段之间往往存在相关性完全独立地取极值等于人为放大了不确定性。改进办法是引入不确定性预算约束限制整个调度周期内偏差的不确定性总量。具体做法是加入一条约束sum(abs(xi_w_t)) R_w其中R_w是总预算然后通过强对偶将不确定线性项转化成对偶变量问题。这样模型仍然保持线性/MILP结构但保守程度大幅下降成本曲线也会更平滑。如果不想把对偶推导做得太复杂还有一个工程上常用的折中方案把全天分成峰、平、谷三个时段组每组分别设置一个鲁棒系数。这样既避免了全时段极值叠加的过度保守又不会让模型变得过于复杂。5.3 代码层面的细节陷阱第一YALMIP中binvar生成的二元变量在求解MILP时必须有整数求解器如果只装了linprog会直接报错。测试前先用yalmiptest确认当前可用的求解器列表别等代码跑起来才发现问题。第二目标函数中的二次项a .* P.^2在YALMIP里可以直接写但如果要用intlinprog必须做分段线性化否则会得到“Objective must be linear”的报错。分段线性化其实不复杂把出力区间切成几段每段用线性成本函数逼近即可切点越多精度越高但变量数也会成倍增加。第三结果可视化时value(RU)返回的维度是N_g×T如果要画总备用曲线记得用sum(..., 1)按机器维度求和而不是按时间维度。这个小问题看起来不起眼浪费了我整整一个晚上的调试时间让我一度以为优化结果有问题。第四脚本文件命名不要带中文。Matlab虽然支持中文注释但中文文件名在部分版本上会导致脚本无法正常运行这个坑不分平台遇到过的人应该都懂。6. 从单时段到多时段扩展的小建议如果要在这套模型上继续做文章我建议优先考虑两个方向。一个是把不确定性预算做成动态调整的比如在负荷高峰时段提高鲁棒系数、低谷时段降低鲁棒系数这样能更精细地平衡可靠性与经济性。另一个是把模型从开机-出力联合优化扩展到包含储能约束储能系统可以在风光大发时充电、负荷高峰时放电相当于给系统增加了一个可双向调节的备用来源对降低鲁棒性成本有立竿见影的效果。在实际使用中我发现把模型从单时段扩展到多时段最大的挑战不是建模本身而是参数的组织方式。每个时段的风电预测值、光伏预测值、负荷预测值、误差区间都要对齐任何一组向量错位优化结果都会悄无声息地偏离真实值。我习惯把所有输入参数塞进一个结构体或者MATLAB表统一从Excel读取不手动在代码里维护数据确保数据一致性和可复现性。如果你只是需要快速验证鲁棒性的影响趋势先从单时段模型开始是性价比最高的路径工具链跑通后再慢慢加时段、加约束。这样万一出问题定位范围也小得多。我已经把这套代码的结构整理成可以复用的模板后续无论换机组参数还是换新能源接入场景只需要改数据文件就能直接跑。
返回列表
PREV
查看更多资讯
NEXT
返回资讯列表