ARTICLE DETAIL

资讯详情

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

微电网鲁棒调度实战:从确定性优化到不确定性建模

微电网鲁棒调度实战:从确定性优化到不确定性建模 做微电网调度的人八成都有过这样的经历前一天的优化方案算得漂漂亮亮第二天早上光伏预测一更新整条调度曲线直接作废。我最早做微电网EMS的日前调度时用的是最经典的确定性优化目标函数里风光出力取预测值、负荷取预测值、电价取预测值求解器一分钟就交卷看起来天衣无缝。结果一到实际运行阴天、多云、跳负荷、电价波动任何一个环节偏离预测所谓的“最优方案”就变成了高额购电的单程票。这篇内容不打算从抽象定义讲起而是一线工程师视角的实战笔记。你会看到一个微电网日前鲁棒调度模型是怎么从确定性版本一步步改出来的包括不确定性怎么建模、预算参数怎么调、求解器怎么写、以及我实际踩过的几个坑。适合正在做微电网EMS、储能系统调度的算法工程师也适合刚接触鲁棒优化、想把它从论文搬到工程里的研究者。1. 微电网里的不确定性比想象中要狠得多1.1 风光出力最不讲信用的一环光伏和风电是微电网里最典型的“随机电源”也是我见过最让调度模型头疼的输入参数。天气预报说晴天你按中午120kW出力建模结果空中飘过一片云十分钟内出力能掉到30kW。风电更夸张风机出力随风速变化而风速本身在时间尺度上就是完全随机的过程风向一变整排风机的出力曲线跟你预测的基本是两条线。这里有个容易被低估的地方预测误差不是均匀分布的它往往集中在高出力时段。光伏在中午达到峰值时云层遮挡造成的绝对偏差最大可能动辄几十千瓦。你如果按固定比例比如±10%建模实际误差在峰值时段可能是±30%以上。反过来夜间光伏出力接近零即使相对误差很大绝对偏差也小得可忽略。所以我在做微电网鲁棒调度时对风光出力的不确定性做了两件事第一按时段统计历史预测误差而不是图省事用一个全局百分比第二把误差的分布形态也记录下来因为后面定不确定集边界、选分位数的时候这个历史分布就是依据。1.2 负荷和电价误差也会要命很多人觉得负荷预测比风光容易得多毕竟用户用电有比较强的规律性。这话在日常场景下大体成立但一旦碰到极端天气、节假日或者某个大用户临时增加产线负荷预测曲线也能给你来一次“惊喜”。微电网的特点是体量小整体负荷可能就一两百千瓦一个大设备启停就是十几千瓦相对误差轻松超过10%。这类偏差在功率平衡约束里同样会传导成购电计划错误。电价的不确定性在电力市场环境下更复杂。现货电价受全网供需、新能源出力、燃料价格多方影响波动幅度远高于微电网内部的负荷波动。如果你的微电网允许向主网购电、售电那电价预测误差会直接影响目标函数里的成本项甚至让“该充该放”的决策整体反转。我遇到过电价预测偏差导致储能策略完全反了的情况模型以为晚上是低谷电价安排了充电实际现货价格却因为风电出力骤减而飙升结果一边充电一边承担高价电费。1.3 确定性优化的“玻璃心”本质确定性优化把所有输入参数当成已知常数求解出的是一组“在预测完全准确的前提下最优”的方案。问题在于预测不可能完全准确而微电网又不像大电网有那么大的惯性可以兜底。打个比方确定性优化就像一个只按天气预报出门的人预报说晴天就绝不带伞。天气预报准的时候确实轻松但一旦预报错淋雨的代价远超“带伞”的那点麻烦。更麻烦的是微电网里的储能容量有限燃气机爬坡有速率限制联络线功率也有上限。当预测偏差出现时这些约束会让你根本来不及补救只能被迫用最贵的现货电来填缺口。从我自己的项目经验看确定性优化方案在实际运行中的“最优”往往只能维持几个时段。只要第一个时段实际和预测出现偏差后面整个调度序列的参考价值就大打折扣这就是我觉得鲁棒优化值得在微电网场景里认真对待的根本原因。2. 鲁棒优化的核心逻辑把最坏情况请进模型里2.1 不确定集给不确定参数画个结界鲁棒优化和传统优化的根本区别是它不再把不确定参数当成一个点而是当成一个集合。这个集合叫“不确定集”用来刻画“实际值可能落在哪个范围内”。最常见也最容易理解的是盒式不确定集也叫箱式不确定集。对光伏出力P_pv(t)如果预测值是P_pv^f(t)预测误差上界是Δpv(t)那不确定集就是P_pv(t) ∈ [P_pv^f(t) − Δpv(t), P_pv^f(t) Δpv(t)]也就是说模型不再只盯着预测曲线那个“点”而是把整条可能的出力区间都纳入考虑。负荷、电价都可以用同样的方式建模。但这里立刻会出现一个问题如果每个时段都允许不确定参数取到区间端点而且所有时段同时取端值那模型会变得极度保守。比如光伏每个时段都取下界、负荷每个时段都取上界等于给系统模拟了一个“全天无风无光且用电爆表”的极端场景这样的方案成本会高得离谱甚至可能出现不可行解。2.2 预算约束给最坏情况上个限流阀为了处理上面说的“过度保守”问题Soyster之后的一批学者发展出了预算鲁棒优化最常用的是Bertsimas和Sim提出的方法。它的核心思想是最坏情况可以发生但不可能所有时段同时发生。你可以用一个预算参数Γ来限制“偏离预测”的时段总量。用我自己的项目来说光伏和负荷一起迭代出一个预算参数Γ含义大致是“全天24个时段里我最多允许几个时段同时处于最坏情况”。Γ0代表完全信任预测退化成确定性优化Γ24代表每个时段都提防最坏情况就是那种极端的盒式鲁棒。实际操作时Γ通常取一个中间值比如6到10代表一天里只为一部分时段的最坏情况做准备。这样一套设计在工程上是说得通的因为光照变化、负荷突变确实有一定的“同时性”但不会像纯盒式建模那样假设全天每个小时都灾难。预算约束相当于给灾难场景上了个限流阀让模型在“太乐观”和“太悲观”之间找到落点。2.3 两层结构为什么适合微电网鲁棒优化的建模思路天然带着“博弈”味道。外层是调度员的决策今天每个时刻机组发多少电、储能充放多少、买多少电这是你现在就要定下来的内层是大自然的选择风光出力、负荷、电价这些不确定参数在最坏的情况下会取什么值。优化目标就是在“大自然选最坏情况”的前提下让外层决策的总成本最低。用微电网的术语说外层变量是“here-and-now”决策比如燃气机的开停机状态、日前购电计划、储能的充放电策略内层变量是“wait-and-see”的扰动结果比如实际光照导致的出力偏差。鲁棒优化把这套博弈变成了一个min-max问题先假定内层取最坏值再找外层的最优解。这种两层结构对微电网特别适合因为微电网里不确定性参数种类多、相关性强、且缺乏足够的历史数据来精确刻画概率分布。随机优化需要给出概率分布模型而鲁棒优化只需要一个区间范围这在工程数据不足的情况下更容易落地。3. 拿一个算例把模型落地从确定性版本到鲁棒版本3.1 算例配置和基础场景为了把过程讲清楚我建了一个不算复杂但足够说明问题的微电网算例。系统包含140kW光伏、50kW风电、100kW/200kWh储能最大充放电功率50kW、60kW燃气轮机以及与主网的联络线最大购电100kW、最大售电50kW。调度周期是24小时时间间隔1小时目标函数是最小化全天运行成本。电网电价采用分时结构峰时段1.0元/kWh、平时段0.6元/kWh、谷时段0.3元/kWh售电价格统一按购电价格的50%计算。光伏预测采用“晴天型”曲线中午11点到14点出力在120kW附近波动全天预测误差边界设为各时段预测值的20%而实际我在算例中还会模拟一个“午后光伏骤降”的场景来测试方案韧性。3.2 确定性日前调度模型怎么写先把基线版本也就是确定性模型摆出来。目标函数是min Σt [ cbuy(t)·Pbuy(t) − csell(t)·Psell(t) ] cgas·Σt Pgas(t)其中cbuy、csell分别是购电和售电价格Pbuy、Psell是购电和售电功率cgas是燃气成本系数Pgas是燃气机出力。因为售电价格低于购电价格模型不会同时既买又卖这个约束可以靠价格机制自然满足。约束条件里最核心的是每个时段的功率平衡Pbuy(t) − Psell(t) Ppv(t) Pwind(t) Pgas(t) Pdis(t) − Pch(t) Pload(t)储能部分用SOC状态变量串联各时段SOC(t) SOC(t−1) ηch·Pch(t)·Δt/Cap − Pdis(t)·Δt/(ηdis·Cap)同时有SOC上下限、充放电功率上下限、联络线功率上限、燃气机爬坡约束。把这些约束和24个时段的决策变量一起丢给求解器就是一个标准的线性规划LP问题CPLEX或Gurobi几秒钟就能出解。3.3 把光伏出力改成区间参数数学上的具体改法现在进入正题。把光伏出力从固定值Ppv^f(t)改成一个有边界的区间参数允许它取到Ppv^f(t) − Δpv(t)到Ppv^f(t) Δpv(t)之间的任意值。负荷也做同样处理用一个Δload(t)表示预测误差边界。直接的做法是把功率平衡约束改成“在最坏情况下也必须满足”的版本。用一个直观的0-1变量写法来说明Pbuy(t) − Psell(t) Ppv^f(t) − zpv(t)·Δpv(t) Pwind(t) Pgas(t) Pdis(t) − Pch(t) Pload^f(t) zload(t)·Δload(t)其中zpv(t)和zload(t)是0-1标志变量等于1表示该时段太阳能取最坏下限、负荷取最坏上限。再用一个预算约束串联起来Σt [ zpv(t) zload(t) ] ≤ Γ这样模型就变成了MIP混合整数规划。这种写法的优点是直观一眼能看出“哪些时段最坏情况被激活了”缺点是24个时段每个时段都要引入二进制变量求解规模上升很快如果系统再大、时段再密计算时间会变得很难看。所以实际工程里我更推荐用Bertsimas-Sim的对偶等价变换把内层max问题通过线性规划对偶转成一组额外约束完全不需要二进制变量模型规模增长有限求解速度比直接MIP快很多。这一步的推导细节这里不展开直接用求解器代码落地更实际。3.4 求解器落地与代码骨架如果你用MATLAB环境YALMIP自带鲁棒优化的建模扩展可以直接声明不确定变量然后照常写约束求解器层面会自动处理对偶问题。我对这个方式保留一个态度YALMIP的鲁棒扩展在中小规模算例上很好用但到了大规模场景它自动生成的等价模型往往不够紧凑运行时间可能焦虑。我更常用的是Python Pyomo Gurobi手动把鲁棒约束写成对偶形式的显式约束。核心代码骨架大概是这样的from pyomo.environ import * from pyomo.opt import SolverFactory m ConcreteModel() m.k range(24) # 决策变量 m.Pbuy Var(m.k, bounds(0, 100), domainReals) m.Psell Var(m.k, bounds(0, 50), domainReals) m.Pch Var(m.k, bounds(0, 50), domainReals) m.Pdis Var(m.k, bounds(0, 50), domainReals) m.SOC Var(m.k, bounds(0.2, 0.9), domainReals) m.Pgas Var(m.k, bounds(0, 60), domainReals) # 鲁棒辅助变量对偶变量 m.alpha Var(m.k, domainReals) m.beta Var(m.k, domainReals) m.gamma Var(domainReals) # 目标函数略 # 功率平衡的鲁棒化约束将对偶后的形式直接写入 def balance_rule(m, t): return ( m.Pbuy[t] - m.Psell[t] pv_f[t] wind_f[t] m.Pgas[t] m.Pdis[t] - m.Pch[t] - m.alpha[t] * delta_pv[t] - m.beta[t] * delta_load[t] - m.gamma load_f[t] ) m.balance Constraint(m.k, rulebalance_rule) # 对偶变量的范围约束 m.con_alpha Constraint(m.k, rulelambda m, t: -1 m.alpha[t] 1) m.con_beta Constraint(m.k, rulelambda m, t: -1 m.beta[t] 1) m.con_gamma Constraint(exprsum(m.alpha[t] m.beta[t] for t in m.k) Gamma)这个骨架里功率平衡约束不再是“预测值刚好相等”而是“在预算所允许的最坏偏差下系统依然能保住平衡”。注意对偶变量alpha、beta的可取值范围是[-1,1]这是Bertsimas-Sim标准形式里的特征直接背下来用就行但前提是你已知晓推导过程中的符号定义。4. 结果不会骗人确定性方案和鲁棒方案的真实差距4.1 正常运行日的对比先看预测完全准确的晴好日。确定性方案出的日运行成本大约是4510元策略也很典型白天光伏出力大储能充到上限晚上低谷电价时段电网充电峰时段储能放电。鲁棒方案在这个场景下日成本大约4870元比确定性方案贵了8%左右。这8%不是白白浪费的你可以理解成给不确定性交的“保险费”。这笔保费体现在什么地方看调度曲线就清楚了鲁棒方案在白天不会把储能电量用得太干净SOC始终多留了10%到15%的余量电网购电计划也比确定性方案更保守避免了“把所有希望寄托在光伏出力峰值”这种脆弱策略。换句话说确定性方案把系统压到了最优边界上而鲁棒方案主动退后一步给自己留了调整空间。4.2 光伏出力的“灾难日”对比为了验证鲁棒方案的真正价值我构造了一个灾难场景午后14点开始光伏出力从预测的120kW骤降到60kW同时16点负荷比预测高了15%。这就是鲁棒模型里最坏情况的部分体现。按确定性方案执行时系统根本没有冗余储能白天已经按计划放完燃气机已经满发联络线功率也顶到上限。面对光伏缺口只能以现货高价补电当天实际运行成本飙到6800元比计划成本高出50%以上。注意这种成本暴涨在工程里还不是最可怕的最可怕的是系统可能直接撞上联络线功率上限甚至触发低频减载。鲁棒方案在同样场景下的表现就好得多。因为建模时就把最坏情况纳入了约束方案保留了足够的储能余量和燃气机爬坡空间面对光伏骤降只需要切一部分负荷、加一部分燃气出力、储能多放一点点当天总成本约5470元虽然比计划成本略高但完全没有出现“超出物理极限”的窘境。两相对比鲁棒方案多支付的保费在灾难日得到了几十倍的回报。4.3 保守度调节Gamma参数怎么权衡Gamma的取值直接决定模型的保守程度。我在这个算例上做了敏感性测试Gamma取值正常运行日成本灾难日实际成本备注04510元6800元退化为确定性优化脆弱44680元5860元保费低抗风险一般84870元5470元相对均衡125100元5310元保费偏高收益递减245560元5230元过度保守日常成本高企可以看到Gamma从0增加到8日常成本涨了8%但灾难日成本降了接近20%Gamma再往上加日常成本继续涨灾难日成本下降幅度越来越小说明边际效益递减。实际项目里我一般不会直接想“Gamma等于多少最好”而是把历史场景回放一遍画出“成本-可靠性”曲线让业主根据对风险的容忍度来做选择。如果业主能接受偶尔1次、2次的高成本事故Gamma可以取小一点如果微电网是给精密制造或医院供电Gamma就得往大调。5. 实战里踩过的几个坑5.1 不确定集边界不是拍脑袋定的最早做鲁棒优化的时候我吃了“边界拍脑袋”的亏。当时为了省事直接把光伏预测误差边界定成±20%建模跑完一看方案保守得离谱储能整天不敢充燃气机一直在备用。后来我把过去三个月的光伏预测和实测数据拿出来统计发现不同时段的预测误差差异很大早晨和傍晚云层复杂误差在30%以上中午晴朗时段稳定误差只有10%左右。按时段动态设定Δpv之后模型保守度立刻下来了成本也更合理。所以我的建议是不确定集边界必须来自历史误差分布一般取90%或95%分位数。如果项目里没有足够历史数据至少也要参考气象预报的置信度来动态调整。千万别拍脑袋定百分比否则你的“鲁棒”只是给自己的模型添堵。5.2 鲁棒解不是万无一失实时修正照样重要还有一个容易产生的误解用了鲁棒优化日前方案就一定能扛住所有情况。实际不是。鲁棒优化只保证不确定集范围内的最坏情况可以应对一旦实际偏差超过了预设边界方案照样失效。比如暴雨天光伏出力比预测低50%而你在不确定集里只考虑到了20%那什么优化都救不了你。所以我在实际项目里用的是一个“日前鲁棒 日内滚动修正”的双层结构。日前层用鲁棒优化定大方向燃气机启停、购电大水、储能的安全区间日内层用滚动MPC每15分钟基于最新实测数据做局部调整。鲁棒优化负责缓解“没有修正能力时”的系统性风险MPC负责处理短时扰动。两者不是替代关系而是配合关系。5.3 对偶变换里的符号容易翻车Bertsimas-Sim的对偶形式看起来很简单但实际写代码时非常容易在符号上翻车。我踩过最典型的坑是把原问题中“≥”方向的不确定约束直接套用对偶公式结果等价的辅助变量取反了解出来之后一检查功率平衡在大多数场景下都不满足而且还很难发现因为MIP不报错目标函数也正常。现在我的习惯是每次写完鲁棒约束都会做一次“场景验证”随机生成上百组不确定参数的真实场景不超出不确定集把求出的决策代回去检查约束是否全部满足。这种随机验证不用很久但能非常快地暴露对偶符号写反、预算约束写漏这类低级错误。5.4 别把随机优化和鲁棒优化混着用最后提醒一下场景选择问题。鲁棒优化的优势是数据需求低、保证性强但有代价它对“概率意义上更可能发生”的普通偏差并不敏感模型只盯着最坏情况这就导致它在平常日子里牺牲了一定的经济性。如果项目有丰富的历史数据能建出比较可靠的概率分布模型那随机优化比如样本平均近似、场景树方法可能在同样成本约束下给出更经济的方案。这不是谁取代谁的问题而是数据量和风险偏好的选择问题。我自己的经验是数据少、风险厌恶、硬性可靠性约束多的时候选鲁棒数据多、允许一定概率失配、追求平均经济性的时候选随机优化。两者结合的两阶段鲁棒-随机混合模型是更进阶的方向但对团队建模能力和求解资源的要求也更高。总的来说微电网调度从来不是“算出一个最优解”那么简单。系统越复杂、分布式电源占比越高不确定性就越突出调度方案离“鲁棒”二字就越近。鲁棒优化不是一个花哨的数学概念它本质上就是让你在不确定性面前保持从容的工具。如果你正在做微电网EMS建议先拿历史数据把误差分布摸清楚再上手建模这条路走通之后你会明显感觉到调度方案从“看着最优”变成了“跑起来也不慌”。
返回列表