尧图网站设计 尧图网站设计YAOTU DESIGN
ARTICLE DETAIL

资讯详情

深耕网站设计与一线实操的经验洞察。

综合能源系统双层优化中的非线性问题与线性化求解策略

综合能源系统双层优化中的非线性问题与线性化求解策略 做综合能源优化这类项目最难熬的往往不是建模本身而是模型写完之后求解器给你撂挑子。我自己在做基于共享储能电站服务的冷热电多微网系统双层优化配置模型这个课题时前后花了大概四个月时间其中一半以上都耗在了非线性问题的处理上。双层优化加上共享储能定价机制稍不注意就会把模型写成MINLP求解时间从几分钟直接飙到几十个小时甚至压根不收敛。这篇文章把我从模型搭建、非线性来源拆解、线性化策略到最终求解的完整过程整理出来重点讲清楚那些非线性项为什么要处理、怎么处理、处理完之后精度和求解速度怎么权衡。内容偏实用适合正在做综合能源优化、多微网协同或者储能规划方向的研究生和工程师参考。1. 项目缘起共享储能与冷热电多微网为什么要放在一起1.1 冷热电多微网的用能特征与三大痛点冷热电多微网说白了就是把若干个同时包含电力、热力、冷负荷的微电网放在一个区域里每个微网内一般都配有微型燃气轮机、余热锅炉、吸收式制冷机、电制冷机、燃气锅炉这些设备实现冷热电联供CCHP。这样一个系统的核心优势是能源梯级利用天然气进燃气轮机发电排出的高温烟气进余热锅炉回收冬季直接供暖夏季推动吸收式制冷机制冷。能量利用率能从传统分供的50%~60%提到70%~85%。但这里有个很现实的问题——单微网规模小负荷波动大典型日曲线往往是上午一个小高峰、傍晚一个大高峰、夜间塌下去。我自己在算例里测过单个微网在夏季典型日冷负荷峰值能到1200 kW但夜间低谷只有200 kW出头峰谷比接近6:1。这种情况下如果每个微网都自己配一套储能投资成本高不说利用率还很低——储能设备一年中有大量时间处于闲置状态尤其是热储能和冷储能季节性强得离谱。要命的是冷热电三种负荷的峰值时刻往往错开电负荷高峰在傍晚冷负荷高峰在下午两三点热负荷高峰在清晨。你按各自峰值去配设备最后每台设备一年真正满负荷跑的时间还不到三分之一这就是综合能源系统里典型的配置冗余、运行低效困境。1.2 共享储能电站的商业逻辑与技术优势共享储能的概念其实是从共享经济延伸过来的由一个独立的投资运营主体建设一座集中式储能电站向区域内多个微网用户提供充放电服务用户按容量或按电量付费不需要自己采购、运维储能设备。这个模式在行业内这几年讨论很多真正落地的示范项目也在增加但大多数公开研究还停留在自建储能的思路上把共享储能作为决策变量的模型并不多见。这个模式在技术上有几个实打实的好处。第一是容量复用不同微网的负荷峰值出现时间不完全重合共享储能电站可以用更小的总容量满足多个微网的调节需求。第二是运行效率集中式储能电站一般用大容量电化学储能锂电或液流充放电效率和循环寿命都比散装小储能更有优势。第三是商业模式灵活可以设计成容量费电量费两部制或者按需定制服务套餐用户侧的固定成本投入大幅降低。在我建的模型里共享储能电站是一个独立的利益主体它和微网之间不是上下级关系而是服务契约关系。这个设定直接影响了后面双层模型的架构——你不能把储能电站当成某个微网的附属设备来处理因为它有自己的投资回报诉求它会通过制定服务价格来引导微网的用能行为。1.3 双层优化配置要解决什么问题配置问题问的是装多少运行问题问的是怎么用。这两个问题在数学上天然耦合——储能容量配置是多少直接决定了运行调度时的可行域反过来调度策略是高效还是低效又直接影响应该配多大的容量才能满足可靠性要求。这就是为什么单层模型做不好这件事如果把运行约束全部塞进配置模型问题规模会爆炸如果先固定容量再算运行又得不到全局最优。双层优化Bi-level Optimization把这两层决策分开建模上层管规划、下层管运行上下层通过共享变量和运行成本反馈互相迭代、最终收敛到均衡解。这是这类项目的主流技术路线也是我在这个课题里采用的框架。2. 双层优化配置模型上层定容量、下层定运行2.1 上层规划层的决策变量与目标函数上层的角色是共享储能电站的投资运营方。决策变量包括储能电站的额定功率MW和额定容量MWh以及是否建设、在哪些站点建设这些0-1变量。如果区域内有多个候选站址还需要加入选址变量这就让上层问题天然带有整数规划的特征。上层目标函数是所有投资方视角下的综合经济性指标一般是年化总成本最小化包含几块储能电站的年化投资成本用等年值法折算。电池本体、PCS变流器、土建和并网设备的投资单价不一样寿命也不同得分开算再乘资金回收系数。年运行维护成本包括固定运维费和随充放电量变化的可变运维费。向电网购电的成本以及向微网购售电的结算费用。共享储能向微网收取的服务费收入这一项在上层目标里是负成本收益。举个例子假设储能单位容量投资成本按1400元/kWh、PCS按800元/kW寿命取10年贴现率取8%那资金回收系数大概是0.149。一座10 MWh/2 MW的储能电站年化投资成本差不多就是 10×1000×1400×0.149 ≈ 208.6万元加上PCS部分2×1000×800×0.149 ≈ 23.8万元光设备折旧就200多万。这个数字直接决定了你不把运行收益做上去共享储能方案根本算不过账。2.2 下层运行层的调度模型下层是每个微网在典型日或者全年8760小时的运行调度问题。目标函数是微网的日运行成本最小化包括向共享储能购电/售电的费用、从上级电网购电的费用、燃气轮机消耗天然气的成本、以及各设备的启停成本。约束条件比上层还多主要是电、热、冷三种能量的逐时平衡约束燃气轮机、燃气锅炉、吸收式制冷机、电制冷机等设备的出力上下限和爬坡约束储能电站的SOC动态方程和充放电功率约束微网与共享储能之间的功率交换约束。这类下层问题是一个典型的混合整数线性规划MILP如果设备台数和调度时段控制在合理规模商用求解器直接就能解。这里有一个关键点下层问题的目标和约束里包含上层传来的参数储能容量上限、服务价格所以下层的最优解本质上是上层决策的函数。这个函数关系是我们后续做线性化处理的核心对象。2.3 上下层耦合机制与求解思路上下层之间靠什么耦合两个东西一是储能电站的额定功率和容量上层定下层把它作为约束上限二是共享储能的服务价格上层定下层作为成本系数。这就构成一个典型的Leader-Follower领导者-跟随者博弈也就是Stackelberg博弈。上层先决策下层在给定上层决策下做最优响应上层再根据下层的响应调整自己的决策直到没有单方面改变策略的动机。处理这个双层问题的主流方法有两种。第一种是把下层问题用KKT条件替代转成单层带互补约束的数学规划问题MPEC再用大M法或者SOS1把互补约束线性化最终得到MILP。第二种是启发式算法上层用遗传算法或者粒子群每一次迭代都调用下层求解器。我的做法是第一种为主因为它能给出理论上有最优性保证的解而不是启发式算法的近似最优。下文会详细展开KKT转化的细节。3. 非线性问题的根源模型中那些不听话的项3.1 二进制变量带来的组合性与逻辑非线性第一个非线性的来源不是函数形式上的非线性而是组合爆炸。只要是带规划性质的问题就离不开0-1变量某个站点建不建储能、某台燃气轮机开不开机、储能处于充电还是放电状态。0-1变量本身不产生数学意义上的非线性项但一旦它和连续变量相乘比如机组运行状态 × 机组出力就出现了双线性项这在数学上属于非凸非线性求解难度陡增。最常见的例子就是储能的充放电互斥约束。很多初学者会写成P_ch(t) × P_dis(t) 0这个约束在物理上是对的——不能同时充放电——但它是非线性的而且是非凸的。非凸意味着可行域不是一块凸的连续区域而是被切成了好几块不连通的碎片这对求解器来说是非常糟糕的。正确做法是引入0-1变量写成一堆线性不等式后面会详细给公式。3.2 效率-出力特性曲线引入的非线性CCHP系统里的设备效率曲线几乎全是非线性的。微型燃气轮机的电效率随负载率变化明显满负荷时能到32%半负荷可能掉到25%以下。如果我们把效率当常数处理误差在部分负荷工况下能超过20%这在工程上完全不可接受。典型的热电联产机组模型里燃料成本通常写成关于出力的二次函数C_fuel a·P² b·P c这个二次函数在目标函数里如果是Min问题且系数是凸的还能用二次规划处理。但如果它出现在约束里或者和其他变量相乘就麻烦了。类似的还有吸收式制冷机的COP随负荷率变化曲线、储能电池充放电效率随SOC变化曲线都是非线性。3.3 共享储能服务定价带来的双线性耦合这是我这个项目里最特殊的一个非线性来源。共享储能电站的服务价格如果是决策变量而不是固定输入参数那么在下层运行模型里微网支付的服务费 结算价格 × 购电量就出现了价格 × 数量的双线性项。这个双线性项还跨越了上下层上层定价格下层出电量。下层的最优电量响应是价格的函数这个函数本身是非线性的实际上是分段线性的因为下层是LP/MILP。所以价格变量进来之后整个双层模型的非凸性进一步增强这是很多同类研究直接把它当作给定参数、不加处理就绕过的原因。但我的观点是服务价格恰恰是共享储能商业模式里最核心的调控杠杆把它作为决策变量模型才能真正回答共享储能电站应该怎么收费这个运营方最关心的问题。3.4 其他隐藏的非线性项还有一些容易被忽略的坑。比如储能寿命损耗模型很多研究用吞吐量累计充放电量来近似寿命损耗吞吐量本身是线性可加的但如果引入充放电深度DOD对寿命的影响就会出现非线性。又比如阶梯电价、需求响应激励这类政策机制本质上是分段函数处理得不好也会引入非光滑项。我在建模阶段做了一个很实用的动作把模型里所有可能出现非线性乘积的地方列了一张清单逐项判断能不能线性化、用什么方法线性化、线性化后会牺牲多少精度。这张表是整个项目中后期没有反复返工的重要原因。4. 线性化策略把非线性问题掰直的实用方案4.1 大M法处理逻辑约束与0-1变量乘积大M法是最基础的线性化工具核心思想是用一个足够大的常数M配合二进制变量把逻辑关系转换成线性不等式组。以储能不能同时充放电为例。设u(t) ∈ {0,1}为充电状态标志位P_ch(t)和P_dis(t)分别是充电和放电功率P_max是最大功率那么% YALMIP中定义约束 P_ch sdpvar(24,1); P_dis sdpvar(24,1); u binvar(24,1); P_max 500; % kW Constraints [P_ch 0, P_dis 0]; Constraints [Constraints, P_ch P_max*u]; Constraints [Constraints, P_dis P_max*(1-u)];当u1时充电功率可以取到P_max放电功率被强制为0u0时恰好相反。这样既满足了互斥约束又保持线性。再举二进制×连续变量的通用处理z x·y其中x ∈ {0,1}0 ≤ y ≤ y_upper。引入辅助变量z满足z ≤ y_upper·xz ≥ 0z ≤ yz ≥ y - y_upper·(1-x)这个公式组特别常用我几乎在每个储能项目里都用到。但这里有个重要的实操细节M的取值非常有讲究。M取得太小比如小于y的实际最大值会错误地削减可行域M取得太大比如1e9会导致求解器数值条件恶化LP松弛质量变差分支定界效率骤降。我的经验是M取实际物理边界的1.5~2倍就够没必要追求大得安全。4.2 分段线性化逼近非线性效率曲线对于效率曲线、成本曲线这类单变量非线性函数分段线性化是标准做法。思路很简单把函数定义域切成N段每段用一条直线近似。在数学上可以用SOS2约束的λ法或者用增量法Incremental Method实现。以燃气轮机的燃料成本二次函数C_fuel a·P² b·P c为例设在出力的定义域[P_min, P_max]内选择断点P1, P2, ..., Pn对应的函数值为C1, C2, ..., Cn。引入非负变量λ1, λ2, ..., λn要求∑λ 1且最多两个相邻的λ非零这就是SOS2约束那么P ∑λi·Pi C ∑λi·Ci用增量法的话则不用SOS2效率更高。具体做法是给每个区间引入一个分段变量δk ∈ [0, 1]表示该区间内的占比配合二进制变量控制区间的连续性。增量法在Gurobi里的表现比λ法好因为它的LP松弛更紧。分段线性化的精度取决于段数。我实测过一个案例燃料成本函数切成5段时目标函数误差约1.8%切成10段误差降到0.4%左右再往上切精度提升就不明显了但求解时间几乎线性增加。所以我在项目中默认取8~10段这是一个精度和效率都比较平衡的点。4.3 McCormick松弛处理双线性项的标准武器对于连续变量×连续变量的双线性项比如w x·yMcCormick松弛是目前工业界最常用的方法。它利用x和y的上下界信息构造w的凸包络。假设x∈[xL, xU]y∈[yL, yU]McCormick包络由四个不等式构成w ≥ xL·y x·yL - xL·yLw ≥ xU·y x·yU - xU·yUw ≤ xL·y x·yU - xL·yUw ≤ xU·y x·yL - xU·yL这四个不等式给出的区域是双线性等式wxy的凸松弛。松弛的紧密程度完全取决于x和y的上下界有多紧。我踩过的坑是如果上层给储能容量的取值范围太宽比如0到100 MWh下层电价变量0到2元/kWhMcCormick松弛出来的区域非常松最终得到的最优解和真实最优解差得很远。解决办法是尽可能收紧变量边界容量上限要根据区域负荷总量来推算服务价格的上下限要根据替代方案比如自建储能的成本、峰谷电价差来标定。边界越紧松弛越紧解的质量越高。下面这张表是我在项目里整理的不同线性化方法适用场景对照着选择能省不少试错时间非线性类型典型场景推荐方法精度损失实现难度0-1变量×连续变量机组启停与出力耦合大M法无精确低单变量非线性函数效率曲线、燃料成本曲线分段线性化可控依赖段数中连续×连续双线性项价格×电量、容量×利用率McCormick松弛较大依赖边界紧度中互补约束双层模型KKT转化大M法或SOS1无精确高4.4 下层LP问题的KKT等效转化处理双层问题的关键一步是把下层优化问题嵌入到上层问题里。如果下层是线性规划LP可以用KKT条件精确替换下层问题得到包含原问题所有变量的单层约束系统。KKT条件包括三组稳定性条件Stationarity拉格朗日函数对各变量求导为零原始可行性Primal feasibility和对偶可行性Dual feasibility原变量和对偶变量满足各自的不等式约束互补松弛Complementary slackness每个不等式约束和对应的对偶变量乘积为零。其中互补松弛条件是非线性的——对偶变量×松弛变量0。对于这种乘积项可以用大M法线性化引入二进制变量和足够大的M把乘积为0等价转化为两条线性不等式。也可以用SOS1约束直接表达两个非负变量中至多一个为正很多求解器原生支持SOS1数值稳定性比大M法更好。这一套下来原来的双层非线性规划就被转换成了单层MILP可以扔给Gurobi或CPLEX直接求解。我在YALMIP里用kkt命令快速搭建原型但在生产版本里是自己手动推导KKT并逐条写成约束的因为YALMIP自动生成的KKT往往带有过多冗余变量求解效率会打折扣。这里需要提醒一个容易踩的坑用KKT条件替换下层问题时必须确认下层问题是凸的线性规划天然满足否则KKT条件只是必要条件而不是充分条件替换之后解出来的均衡可能根本不是下层的最优响应。如果你实在需要处理非凸的下层问题就得考虑用启发式算法或者对偶间隙分析那复杂度会上一个台阶。5. 求解框架搭建与算例验证从模型到结果的最后一公里5.1 建模平台与求解器选择我的技术栈是MATLAB YALMIP Gurobi。选这几个工具的原因是YALMIP建模快适合快速验证模型逻辑Gurobi的MILP求解器在同类软件里目前是性能天花板尤其是它的Presolve和分支策略对于这种动辄几万个变量的大模型非常关键。如果你偏好开源方案Python Pyomo CBC也能做但在大规模MILP上求解速度差距还是比较明显的。我自己的建议是初期模型调试可以用开源求解器跑通逻辑最终数值实验用商用求解器出结果。Python生态里还有一个值得关注的库叫PAOPyomo Algebraic Optimization专门做双层优化但成熟度还有待观察。求解器参数设置有几个值得注意的点。MIPGap建议设到0.1%甚至0.05%我项目里的目标函数是千万级别的年化费用0.1%的gap对应几千块钱的误差可以接受。TimeLimit要结合算例规模设置我在72时段×5微网的算例下一般给3600秒上限。另外Gurobi的MIPFocus参数也很关键如果模型主要是为了搜索可行解设成1如果上界已经很好但想证明最优性设成3。我在项目中后期把MIPFocus设为2强调最优性求解器更倾向于对当前最优解做改善而不是漫无目的地探索新区域。5.2 算例参数设计与场景构建算例设计的好坏直接决定项目报告的说服力但这个环节最容易翻车。我的做法是分三步。第一步定系统拓扑。我采用了3个冷热电联供微网1座共享储能电站的典型结构3个微网的负荷曲线分别设为居民型、商业型和工业型峰值错开这样能充分体现共享储能的容量复用价值。居民型负荷晚高峰明显商业型负荷白天平稳、傍晚骤降工业型负荷全天波动小而基数大。三者的合成负荷曲线比任何单一微网都平滑得多。第二步设设备参数。每台微型燃气轮机的额定功率设为500 kW电效率曲线取典型数据余热回收率0.65吸收式制冷机COP取1.2电制冷机COP取3.5锂电池储能的充放电效率各取0.95。这里要特别强调的是设备参数不要只从厂家手册抄最好用实测数据或者至少是经过同行评议的文献数据否则审稿人一问数据来源就尴尬了。第三步是场景设置。为了控制计算量我选了夏季典型日、冬季典型日、过渡季典型日各1天每天24个时段一共72个调度时段代表全年的运行情况。这样比直接跑8760小时省一个数量级的计算时间同时能覆盖主要工况。每个典型日的权重分别为0.25、0.25、0.5全年来看过渡季时间最长这个权重系数直接乘在运行成本上可以换算成年化值。5.3 结果对比与关键指标我跑了四组对照实验方案一每个微网自建储能方案二使用共享储能但服务价格固定方案三使用共享储能且服务价格为决策变量方案四是理想情况不考虑储能容量约束作为成本下限参考。几个重点看的数据总年化成本共享储能方案比自建方案低大约18%~25%这个差异主要来自容量复用和规模效应储能利用率共享储能电站的年等效充放电循环次数比各微网自建储能高出一倍以上求解时间线性化之后MILP求解时间在200~1500秒之间同一个问题如果不做线性化直接交给非线性求解器不仅慢而且经常找不到可行解。还有一点想提醒算例结果一定要做敏感性分析。我测试了共享储能服务价格从0.2元/kWh到0.8元/kWh变化时各微网的最优容量配置和成本变化。结果发现价格超过0.6元/kWh以后部分微网会选择减少向共享储能购电、增加自己机组的出力这说明价格信号对用户行为有很强的引导作用——这个结论对共享储能的运营定价有直接参考价值。6. 踩坑记录与工程落地体会6.1 Big-M取值是线性化精度和数值稳定性的命门整个项目里我在这上面翻过两次车。第一次是M取值太小导致某些可行解被切掉了结果看起来很理想但实际上是错误的可行域。第二次是另一个参数M取到了1e8求解器在分支定界时数值混乱出现了一些诸如0.0001 0的荒谬矛盾。我现在养成了一个习惯每一个M都手动核对数量级全模型扫描一遍保证M相对于该约束里的最大可能量级只大一个数量级左右。宁可多花半小时做这一步也好过求解器跑了两小时给你一个数值噪声导致的次优解。在Gurobi里还可以开启NumericsFocus参数设为2或3让求解器在数值困难时自动切换到更稳健的算法路径但这个只能兜底不能依赖。6.2 求解时间与模型规模的博弈双层优化最大的现实挑战是真难收敛快。KKT转化之后的MILP变量数量是原问题的好几倍尤其互补约束需要引入大量二进制变量分支定界的搜索树会变得很深。我的经验是三个降规模的技巧。第一对称性破坏微网如果结构和参数相似会存在大量对称解求解器会在这些等价解之间反复搜索。加一些对称性破坏约束symmetry breaking constraints比如按负荷大小给微网排序、要求容量配置随负荷非递减能显著加速求解。第二初始解注入先用一个简化模型比如把共享储能服务价格固定跑出一个可行解作为MILP的MIP start让求解器在分支定界一开始就有一个好的上界。实测这一步能把求解时间压缩30%~40%。第三适当合并时段如果对精度要求不那么苛刻把24时段合并成12个两小时时段模型规模直接减半。6.3 线性化精度与模型保真度的取舍线性化本质上是用可解性换保真度。McCormick松弛给出的是原问题的松弛解如果松弛太松最优值会比真实值偏低你以为省钱省了很多实际做不到。分段线性化则相反是给原问题加了近似约束最优值可能会比真实值略高。我在项目报告里都是这样处理的在3个微网的小规模算例上用非线性求解器比如SCIP直接解MINLP问题拿结果和线性化模型的结果做对比。如果两者的目标函数差距在3%以内就认为线性化策略是可接受的如果超过5%就需要加密分段数或者收紧边界重新求解。这个线性化前后验证步骤在审稿和项目评审时非常加分它证明你的线性化不是拍脑袋。6.4 工程落地层面的几点思考最后聊点模型之外的东西。共享储能电站在真实世界落地难点远不止数学建模。第一个体之间的信任和结算机制——多微网共享一个储能谁用了多少电、谁该付多少钱需要透明可信的计量和结算系统这是目前很多示范项目卡壳的地方。第二个是调度权归属——共享储能的充放电指令由谁下发独立运营商、微网聚合商还是电网调度不同模式对应的模型结构完全不同。第三个是边界条件——真实工程里储能还要参与一次调频、备用、需求响应等辅助服务收益来源比模型里的峰谷套利容量费复杂得多。我在这篇模型里没有把这些服务都展开但它们完全可以作为约束条件或收益项加进来。我在后续的研究方向里会把这些机制设计问题和优化模型结合起来做比如在双层模型里加入收益分配机制、考虑多主体之间的合作博弈以及把共享储能的服务模式从按电量结算扩展到容量租赁辅助服务的多元套餐。模型从论文走向工程中间的路还很长但先把非线性这座山翻过去后面的事会顺很多。如果这篇内容能帮你在建模和求解的路上少走点弯路那这些坑就算没白踩。
返回列表