ARTICLE DETAIL

资讯详情

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

双层优化视角下分布式储能容量配置:改进粒子群与CPLEX联合求解

双层优化视角下分布式储能容量配置:改进粒子群与CPLEX联合求解 分布式能源并网后的储能容量优化我最近刚把一个实际项目跑完过程挺折腾的从模型搭建到求解器调试踩了不少坑。思路用一句话概括就是外层用改进粒子群搜容量配置内层交给CPLEX求最低购电成本运行策略两层叠起来形成一个闭环的双层优化框架。如果你手头也在做微电网、园区配电网或者光储充项目的容量规划这篇文章应该能帮你省下不少试错时间。先说说为什么这个题目值得专门写一篇。储能容量优化这事看起来就是一个买多大电池的选择题但实际做的时候你会发现容量不是一个独立变量它的经济价值完全取决于后续怎么运行——充放电策略、分时电价下的套利空间、与光伏出力的匹配度这些都会反过来决定容量选得合不合理。把这两层关系一起优化的过程就是双层优化模型要解决的。再加上CPLEX这种商业求解器在国内学术界用得非常多但配置到MATLAB这一关就能卡住不少人所以我把整套方案的建模思路、代码骨架和实战经验都整理在下面了。1. 分布式能源并网后的储能容量困境为什么拍脑袋式配置会翻车1.1 光伏和负荷的时空错配让储能容量变成一个耦合问题先看一个典型场景。某园区配电网光伏装机6MW负荷曲线是典型的双峰型上午10点到下午3点有一个小高峰晚上6点到10点是全天最大负荷段。问题在于光伏出力峰值出现在正午而负荷峰值出现在傍晚中间隔了三四个小时。这就引出了所谓的净负荷曲线负荷减光伏出力——正午时段净负荷被光伏压得很低傍晚光伏归零后净负荷迅速爬升形成一条被业内称为鸭子曲线的深U形曲线。没有储能的情况下电网调度必须按这条净负荷曲线的最高点来配置联络线容量而且光伏大发时段弃光率很高。储能在这里的作用机制其实就三件事削峰填谷、套利移峰、平抑波动。但每件事的收益都和容量、功率配置强相关——容量MWh决定能搬移多少电量功率MW决定能在多短时间内搬移这些电量。两者是需要独立决策的变量而它们的合理取值又必须结合给定的电价曲线和负荷曲线去推演实际运行过程才能算清楚。1.2 传统估算方法为什么容易翻车很多人一开始会走捷径按负荷峰谷差的固定比例估一个容量或者参考同类项目的功率/容量比直接套用。我在开头提到的那个园区项目就是这么翻车的——当时按经验值配了2MW/4MWh运行三个月后SOC长期在低位徘徊原因是该园区的峰谷电价差不足以支撑每天两充两放的套利策略储能系统大部分时间处于闲置状态投资收益率远低于测算值。问题出在什么地方单层优化把运行策略简化了。常见的单层储能容量模型要么假设储能按固定倍率充放电要么用一个固定的有效利用小时数折算容量价值这些处理都绕开了容量是上层决策、运行是下层应对这个基本事实。实际运行中储能每天怎么充、怎么放、SOC维持在什么区间是一个动态决策过程它直接决定了给定容量下储能的年度经济收益。把这个过程简化掉容量配置结果怎么可能准确1.3 双层结构本质上在回答什么把问题拆成两层来看就清晰了上层规划层决策储能系统的额定功率和额定容量目标是让全生命周期内的年综合费用最小。这一层的时间尺度是年考虑的是投资成本的等年值分摊。下层运行层在给定储能容量后以24小时为周期优化每一时段的充放电功率和购电功率目标是购电成本最低。这一层的时间尺度是日甚至小时。两层之间是典型的Stackelberg主从博弈关系上层先出牌给出容量配置下层在约束范围内理性应对追求自身购电成本最小化上层根据下层的应对结果评估自己这步棋的收益再调整下一步。这种结构恰恰是储能容量问题的本质——容量投资的回报与否取决于储能后续能否通过合理运行把成本省回来。2. 为什么选外层改进粒子群、内层CPLEX的组合2.1 外层搜索空间让梯度类算法直接出局先跑一个简单的测算上层的决策变量只有两个额定功率和额定容量但目标函数计算一次需要完整求解24时段的运行优化问题而且投资成本、等年值系数叠加之后目标函数是高度非线性的。如果我只用这两个变量做网格搜索假设每个变量取30个候选值光外层就要算900次内层LP求解——这还是没考虑约束组合的情况。传统的数学规划方法在这种结构面前很吃力。经典的思路是把下层优化问题用KKT条件替换把双层问题转成单层MPEC带均衡约束的数学规划问题但前提是下层问题足够干净——最好是线性规划且满足约束规范。实际工程里如果下层要引入机组启停的0-1变量或者储能充放电互斥约束需要用整数变量表达KKT转换就会变得非常复杂甚至不可行。2.2 粒子群在外层的三个优势相比之下粒子群算法处理这个外层规划问题是比较合适的理由有三对目标函数的黑箱性不敏感。外层目标函数里嵌着内层优化结果相当于一个隐式函数没有显式梯度。粒子群只需要能算出适应度就能推进搜索这一点上它和网格枚举是同一类思路但搜索效率高得多。决策变量维度低。外层通常只有2-3个连续变量粒子群在这种低维连续空间的搜索能力完全够用不容易出现高维问题里常见的维度灾难。实现成本低、参数直观。相比遗传算法需要设计编码、交叉和变异算子粒子群只需要维护速度和位置两组矩阵参数的物理意义也很直白——惯性权重控制全局搜索和局部开发的平衡学习因子控制向个体最优和全局最优学习的强度。这并不意味着直接套用标准粒子群就行。标准PSO有个毛病大家应该都遇到过迭代中期粒子快速向当前全局最优靠拢如果这个最优是个局部极值整个种群就早熟了。针对这个问题我做了两个改进后面代码部分会详细写一是惯性权重非线性递减策略让算法在前期保持较好的全局探索能力后期再收敛到局部精细搜索二是加入扰动变异机制每隔一定代数对当前全局最优粒子的位置做一个小幅随机偏移相当于给种群换气。实测这两个改进在储能容量问题上效果很明显收敛曲线明显更平滑最终目标值也更优。2.3 内层为什么必须用精确求解器内层购电成本优化问题写出数学形式之后其实是一个线性规划LP——目标函数是购电功率与电价的线性乘积之和约束都是线性不等式和等式。只要储能充放电不互斥约束用线性化表达整个问题就是一个非常标准的LP。对于LP粒子群这类启发式算法反而是最不该用的——你完全可以求出全局最优解为什么要用一个可能收敛到局部最优的近似算法去碰运气CPLEX在这个场景下的优势是碾压性的求解精度高。单纯形法或对偶单纯形法给出的解是数学上最优的不依赖任何初始解。求解速度快。一个24时段、几十个约束的LP对CPLEX来说是小到不能再小的规模单次求解时间一般在毫秒级到几十毫秒级。数值稳定性好。不像自己写的LP求解器可能遇到病态矩阵、退化和数值溢出的问题CPLEX内部处理得很成熟。所以这个组合的逻辑就是元启发式算法负责外层搜索空间探索商业求解器负责内层运行优化精确求解。各干各擅长的事组合起来反而比任何一端单打独斗都稳。有一句我常跟学生说的话如果你的项目里内层问题明明是个标准LP却非要用GA去解那不叫算法创新叫给自己挖坑。3. 双层模型怎么搭数学表达、约束与内外层数据流3.1 外层规划模型投资决策层先把符号定义清楚。设储能的额定功率为(P_{s})MW、额定容量为(E_{s})MWh这就是上层要决策的两个变量。上层目标函数是年综合费用最小[ \min_{P_s, E_s} ; C_{total} C_{inv} C_{om} C_{buy} \times N_{day} ]其中(C_{inv})是储能投资成本的等年值计算公式为 [ C_{inv} (c_p P_s c_e E_s) \times CRF(r, Y) ] 这里(c_p)是功率成本系数万元/MW含PCS、变压器等(c_e)是容量成本系数万元/MWh含电池本体、BMS、温控等(CRF(r, Y))是等年值系数也叫资金回收系数表达式为 [ CRF(r, Y) \frac{r(1r)^Y}{(1r)^Y - 1} ] 其中(r)为折现率(Y)为储能系统寿命年限。这个系数的作用是把当前一笔一次性投资均匀摊到寿命期内的每一年。比如(r8%, Y10)年(CRF \approx 0.149)意味着一次性投入1000万等效于每年支付149万含资金的时间成本。(C_{om})是年运行维护费用一般按投资成本的一定比例估算我这里取2%。(C_{buy} \times N_{day})是全年购电成本其中(C_{buy})是内层优化得到的典型日购电成本(N_{day})是一年的运行天数工程上可以直接取365如果考虑检修停运可以打折。外层约束主要就是决策变量的取值范围[ P_s^{min} \le P_s \le P_s^{max}, \quad E_s^{min} \le E_s \le E_s^{max} ]如果站点有场地面积限制还可以加一个容量-功率比约束比如(E_s / P_s)落在储能倍率的合理区间内锂电池一般0.5C~2C即储能倍率C-rate。3.2 内层运行模型运行决策层给定上层的(P_s)和(E_s)后内层以24小时为优化周期目标是典型日购电成本最低[ \min ; C_{buy} \sum_{t1}^{24} price(t) \cdot P_{buy}(t) \cdot \Delta t ]决策变量包括每时段的购电功率(P_{buy}(t))、储能充电功率(P_{ch}(t))、放电功率(P_{dis}(t))、以及每个时段末的SOC值(SOC(t))。约束条件我按五组来梳理都是我在代码里实际用到的1功率平衡约束[ P_{load}(t) P_{buy}(t) P_{pv}(t) P_{dis}(t) - P_{ch}(t) ]这个等式说明每个时刻负荷由三部分供给购电、光伏出力和储能放电充电相当于增加了负荷侧的消耗。如果你需要双向潮流或考虑售电给电网可以在(P_{buy})上扩展成购售双向决策但本文按不可逆购电处理。2储能SOC递推约束[ SOC(t) SOC(t-1) \left( \eta_{ch} P_{ch}(t) - \frac{P_{dis}(t)}{\eta_{dis}} \right) \cdot \frac{\Delta t}{E_s} ]这个式子的物理含义是当前时刻的剩余电量等于上一时刻的剩余电量加上充电带来的增加量乘以充电效率减去放电带来的消耗量除以放电效率因为放电时电池端放出的能量大于电芯内部消耗的能量。3SOC上下限约束[ SOC_{min} \le SOC(t) \le SOC_{max} ]为了保护电池寿命一般设置SOC工作区间在10%~90%之间初始SOC和日末SOC可以根据调度需求固定比如都设成20%。4充放电功率约束[ 0 \le P_{ch}(t) \le P_s, \quad 0 \le P_{dis}(t) \le P_s ]这一组约束直接体现了上层决策变量(P_s)对内层可行域的影响也是两层耦合的直观体现。5充放电互斥约束严格来说同一时刻不能既充电又放电。如果引入0-1变量(u(t))约束为[ 0 \le P_{ch}(t) \le u(t) P_s, \quad 0 \le P_{dis}(t) \le (1-u(t)) P_s ]这会内层变成MILP混合整数线性规划。实际工程里有一个更轻量的处理方式用线性约束[ P_{ch}(t) P_{dis}(t) \le P_s ]替代。为什么可行因为在购电成本最小化的目标下如果电价低时充电获利、电价高时放电获利控制器自然会把功率导向单一方向不会出现边充边放这种自我抵消的浪费行为。在大量算例中两者的结果差异基本可以忽略。强烈建议工程版本先用这个线性替代把内层保持为LP求解速度快一个数量级。3.3 内外层数据交互的完整闭环现在把整个求解逻辑画成流程来描述外层粒子群在当前迭代中生成一组((P_s, E_s))作为参数传入内层模型内层CPLEX求解得到该容量配置下的最优运行策略和购电成本购电成本返回外层外层按年综合费用公式计算该粒子的适应度然后粒子群根据适应度更新速度和位置生成下一组容量配置不断迭代直到达到最大迭代次数或收敛精度要求。注意内层返回的不仅仅是购电成本一个数还包括最优SOC曲线和充放电功率曲线这些数据在结果分析阶段非常有用——你可以直接观察某个容量方案下储能是否被充分利用是容量瓶颈还是功率瓶颈在制约系统表现。4. MATLAB调通CPLEX的关键配置与代码骨架4.1 CPLEX装在MATLAB里最容易卡住的三个环节这个部分单独拎出来写是因为我见过太多人在这一步折戟了。CPLEX本身是个独立的商业求解器核心求解引擎是C写的MATLAB要调用它需要通过官方提供的MATLAB接口。第一步是版本兼容性检查。CPLEX 12.x系列和MATLAB的兼容情况需要在官方文档里对照确认。以我用的CPLEX 12.9为例官方支持MATLAB R2016b到R2019b如果你用MATLAB R2020之后的高版本可能需要升级到CPLEX 20.1或22.1。在安装之前一定要先查兼容列表否则装完报错Unable to load cplex你会怀疑人生。第二步是路径配置。安装完IBM ILOG CPLEX Optimization Studio之后找到安装目录下的Matlab接口文件夹典型路径是C:\Program Files\IBM\ILOG\CPLEX_Studio129\cplex\matlab在MATLAB命令窗口执行addpath(genpath(C:\Program Files\IBM\ILOG\CPLEX_Studio129\cplex\matlab)); savepath;注意用genpath而不是addpath因为matlab目录下还有按具体版本号分的子目录比如matlab\x64_win64genpath会把所有子目录一次性加入。配置完成后用which cplexlp验证一下能返回路径说明接口挂上了。第三步是通过YALMIP做建模层。我不太推荐直接用CPLEX的裸函数cplexlp写约束——代码可读性太差改模型时更是灾难。推荐用YALMIP工具包做建模层底层求解器指定为CPLEX即可。YALMIP配置CPLEX只需要一行options sdpsettings(solver, cplex, verbose, 0);如果你不确定YALMIP有没有正确识别CPLEX运行yalmiptest看输出里CPLEX那一行是否显示passed。4.2 内层运行优化模型的代码骨架内层模型的YALMIP代码如下这个版本是一个可以直接跑通的24时段LP%% 内层模型给定储能配置求最小购电成本 P_s 2; % MW外层传入 E_s 4; % MWh外层传入 eta_ch 0.95; % 充电效率 eta_dis 0.95; % 放电效率 dt 1; % 时段长度单位h SOC_min 0.1; SOC_max 0.9; SOC_init 0.2; SOC_final 0.2; % 已知曲线P_load(1,24), P_pv(1,24), price(1,24) 单位MW/元每kWh % 决策变量 P_buy sdpvar(1, 24); P_ch sdpvar(1, 24); P_dis sdpvar(1, 24); SOC sdpvar(1, 24); Constraints []; % SOC初始值 Constraints [Constraints, SOC(1) SOC_init]; for t 1:24 % 功率平衡 Constraints [Constraints, P_load(t) P_buy(t) P_pv(t) P_dis(t) - P_ch(t)]; % 充放电功率边界 Constraints [Constraints, 0 P_ch(t) P_s]; Constraints [Constraints, 0 P_dis(t) P_s]; % 互斥线性松弛 Constraints [Constraints, P_ch(t) P_dis(t) P_s]; % SOC上下限 Constraints [Constraints, SOC_min SOC(t) SOC_max]; if t 1 % SOC递推 Constraints [Constraints, SOC(t) SOC(t-1) (eta_ch * P_ch(t-1) - P_dis(t-1)/eta_dis) * dt / E_s]; end end % 日末SOC回落到设定值可选保证日内能量守恒 Constraints [Constraints, SOC(24) SOC_final]; Objective sum(price .* P_buy * dt); options sdpsettings(solver, cplex, verbose, 0); optimize(Constraints, Objective, options); C_buy value(Objective);有几个细节说明一下SOC没有定义为25个变量、把第25时刻作为次日零点而是用SOC(1)作为初始值、SOC(24)作为日末值这样变量少一些求解更快。另外P_load、P_pv、price这些在循环外作为参数传入单位统一成MW和元/kWh即可购电成本算出来的单位是千元如果price按元/kWh功率按MW乘积会差一个1000的量级注意换算。4.3 外层改进粒子群的主框架外层PSO的代码结构如下重点是惯性权重的递减和变异机制%% 外层PSO参数 nP 30; % 粒子数 maxIter 100; % 迭代代数 c1 2.0; c2 2.0; w_max 0.9; w_min 0.4; % 决策变量范围[P_s, E_s] lb [0.5, 2]; % 功率下限0.5MW 容量下限2MWh ub [5, 20]; % 功率上限5MW 容量上限20MWh dim 2; % 初始化 X repmat(lb, nP, 1) rand(nP, dim) .* (repmat(ub - lb, nP, 1)); V zeros(nP, dim); pbest X; pbest_fit inf(nP, 1); gbest zeros(1, dim); gbest_fit inf; for iter 1:maxIter % 计算每个粒子的适应度调用内层模型 for i 1:nP P_s_i X(i, 1); E_s_i X(i, 2); % 这里调用内层函数返回年综合费用 fit_i calTotalCost(P_s_i, E_s_i); if fit_i pbest_fit(i) pbest_fit(i) fit_i; pbest(i, :) X(i, :); end if fit_i gbest_fit gbest_fit fit_i; gbest X(i, :); end end % 惯性权重线性递减 w w_max - (w_max - w_min) * iter / maxIter; % 每30代对全局最优做一次扰动变异 if mod(iter, 30) 0 gbest gbest 0.05 * (ub - lb) .* randn(1, dim); gbest max(lb, min(ub, gbest)); end % 速度与位置更新 for i 1:nP V(i, :) w * V(i, :) c1 * rand(1, dim) .* (pbest(i, :) - X(i, :)) ... c2 * rand(1, dim) .* (gbest - X(i, :)); X(i, :) X(i, :) V(i, :); % 边界处理越界回弹 X(i, :) max(lb, min(ub, X(i, :))); end end改进粒子群的两个设计点在这里解释一下惯性权重线性递减的思路是迭代初期用大的(w)比如0.9让粒子保持高速探索避免过早陷入局部最优迭代后期用小的(w)比如0.4让粒子在局部范围内精细搜索。变异扰动则是在搜索停滞时强行把全局最优粒子踢到邻域空间里探索防止整个种群收缩到同一个点后就再也跳不出来。关于内层调用方式这里有一个性能优化的小技巧值得强调不要在每次粒子评估时都用YALMIP重新建模而是把模型结构固定住。具体做法是在内层的MATLAB函数中把不随((P_s, E_s))变化的负荷曲线、光伏曲线、电价这些数据一次性加载到工作区每次迭代内层只用assign函数更新P_s和E_s对应的参数值然后重新调用optimize。这样可以省掉重复转换模型的时间开销整体速度提升非常明显。5. 典型日算例参数设定、结果解读与调参手记5.1 算例基础数据我用的算例来自一个实际园区项目的典型日数据。分时电价采用峰平谷三段式详细参数如下时段电价元/kWh说明23:00-07:000.32谷段07:00-10:00、15:00-18:00、21:00-23:000.68平段10:00-15:00、18:00-21:001.12峰段负荷曲线在凌晨4点达到全天最低12MW晚上7点半左右达到峰值28MW光伏出力正午12点最高8MW晚上8点后归零。储能参数如下参数数值说明功率成本系数 (c_p)80万元/MWPCS及并网设备容量成本系数 (c_e)120万元/MWh电池系统含BMS寿命年限 (Y)10年按日历寿命折现率 (r)8%资金成本充电/放电效率0.95/0.95锂电池典型值SOC运行区间[0.1, 0.9]保护电池5.2 最优配置结果与成本结构用30个粒子跑100代算例给出的最优配置约为2.3MW/6.5MWh年综合费用构成大致为投资等年值约160万元/年年运维费用约20万元/年年购电成本约2450万元/年相对于无储能方案下降了约8.5%这里有一个有意思的现象光看购电成本的绝对下降值一年可能只省了200万出头这和储能投资的等年值一对比回收期接近甚至超过寿命周期。这说明一个问题——单靠峰谷电价套利在当前电价结构下储能经济性通常是不达标的。所以实际项目中储能容量的价值评估往往还要叠加需量电费管理、需求响应补贴、降低备用容量费用等附加收益。我特意把这个结果写出来是希望大家在跑模型时心里有数如果某篇论文声称双层优化后储能在第3年回本建议先检查是不是把电价差设置成了0.9元以上的极端场景或者把投资成本压到了500元/kWh以下。这些参数在实验室里可以调但在工程测算里要非常谨慎。5.3 SOC曲线与充放电策略分析最优配置下的SOC曲线呈现出非常规律的谷充峰放模式夜间谷段电价0.32元/kWh时充电SOC从20%逐步爬到90%上午平段小幅放电维持午前小高峰正午光伏大发时充电相当于把本来可能弃掉的光伏电量存起来傍晚峰段再大功率放电覆盖晚高峰。整个过程两充两放电池循环次数约1.8次/天基本接近日常运营的合理强度。如果观察不同容量配置下的SOC曲线你会发现一个颇有参考价值的规律当容量配置过小比如2MWh时储能每天晚上一到峰段就把电放完了后半段负荷高峰完全靠购电硬顶当容量配置过大比如15MWh时SOC在中段就长期卡在上限附近电池吃不饱有效吞吐率反而下降。这两类现象都对经济性不利。这也验证了前面说的——容量和功率的最优值本质上是被运行策略逼出来的。5.4 PSO调参手记调参这块我直接分享实测结论省得大家重复踩坑粒子数维度只有2维时30个粒子足够。增加到50个以上对最终结果影响很小但内层求解次数线性增加总耗时翻倍。迭代次数80到100代通常已经收敛继续迭代到200代收益极低。判断收敛的标志是gbest_fit曲线在最后20代基本是一条水平线。学习因子(c_1c_22)是标准配置基本不需要动。如果发现收敛过快、容易早熟可以适当加大(c_1)增强个体探索。惯性权重0.9到0.4的线性递减版本在大多数算例上表现不错。如果想进一步改进可以用非线性递减——前期衰减更慢、后期衰减更快配合变异扰动效果更好。如果基础PSO经常收敛到不同结果多跑几次最优值差异超过2%说明种群多样性不足优先检查变异机制是否生效而不是盲目加大迭代次数。6. 工程落地中的踩坑记录与方案扩展6.1 内层报Infeasible problem时的排查链路这个报错我在项目里遇到过好多次每一次的原因都不太一样。最有效的排查方式是三步走第一步把外层传进来的容量参数固定成一组已知可行值单独跑内层模型确认模型本身能不能求解。如果单独跑也报不可行说明约束之间存在矛盾。第二步用松弛法定位矛盾约束——先把SOC区间放宽到0到1再放开充放电功率上限逐个恢复约束看是哪一步触发了不可行。在我遇到的情况里最常见的原因有两个一个是日末SOC必须回到初始值的约束加上充放电效率损失导致一天的净充电量不足以满足这个回升需求另一个是储能功率太小无法在低谷时段完成足够的充电量来支撑晚间放电。前者可以通过把SOC初值/末值调整到合理范围比如允许日末落在20%至50%区间而不是刚性固定后者说明外层给的内层可行域太窄需要扩大PSO的搜索范围。第三步如果模型加了互斥的0-1整数约束检查YALMIP里binvar声明的变量个数和约束索引是否匹配这类问题报错虽然提示是infeasible但根因其实是建模时的索引错位。6.2 粒子群早熟收敛的识别与处理在储能容量这个场景里早熟有一个很典型的特征全局最优集中在某个功率/容量组合附近但这个组合在工程上显然不是最合理的比如储能倍率高达3C明显超过锂电池正常倍率范围。这说明PSO过度聚焦在搜索空间的某个角落没有充分探索其他合理区域。我的处理方案是两层一是前面代码里的周期变异把全局最优小概率扰动到邻域二是增加重置粒子逻辑——如果连续N代gbest_fit没有任何改善随机选取种群里30%的粒子重置到随机位置但保留它们的历史pbest信息。这样既维持了种群多样性又从记忆里保留了已有搜索成果。还有一个容易被忽略的细节边界处理方式。粒子越界后用截断还是回弹对收敛性影响很大。截断会让大量粒子堆在边界上导致边界处看似是全局最优其实是被迫堆积我推荐用带衰减的回弹方式处理越界让粒子越界后向搜索空间内部弹回避免边界粒子扎堆。6.3 计算效率优化从场景聚类到热启动双层优化的最大痛点其实是计算时间尤其当你有几十个典型日要分别求解时。如果你的项目涉及一年的时序数据我的建议是先用K-means算法对全年365天的负荷-光伏-电价组合做场景聚类挑出3到5个代表性典型日场景将各场景的购电成本按天数占比加权求和后再作为内层返回值。这样计算量直接下降一到两个数量级而且因为场景代表性充分配置结果基本不会偏离全时序优化太多。另一个优化技巧是热启动由于内层LP的结构在迭代中保持不变CPLEX在求解第(k1)个粒子时可以利用第(k)个粒子求解得到的基础解信息作为初始点。具体到YALMIP层面可以在循环内调用optimize之前不重建模型只更新决策变量参数CPLEX会自动利用上一次求解的内部状态。这个功能默认就是开启的前提是你的模型变量和约束结构在循环内保持完全一致。6.4 模型扩展的三个方向这个双层框架的扩展性很好我实际中试过的几个方向内层加网络约束如果从单节点模型扩展到IEEE 33节点等配电网拓扑内层LP就变成带潮流约束的最优潮流问题CPLEX依然可解直流潮流假设下保持线性但计算量会上一个台阶。外层加多目标在年综合费用最小之外把碳排放约束或弃光率约束作为第二目标用多目标粒子群MOPSO替换单目标版本可以生成Pareto前沿供决策者选择。考虑电池容量衰减锂电池的可用容量随循环次数衰减如果规划年限较长可以给外层目标函数里加一个容量衰退因子让等年值成本更贴近实际。这部分会增加模型复杂度但结果更可信。最后再分享一个我在实际项目里的体会双层优化模型跑出的结果只是决策支持——它告诉你哪个容量区间在给定条件下最经济而不是一个必须精确到小数点后两位的铁律。真正落地时还要考虑设备选型的离散规格比如电池模组只能按100kWh整数倍扩充、安装场地限制、甚至电网公司的并网批复条件。所以在给业主交付结论时我通常会在最优解附近拎出2到3个接近最优的可行方案把各自的边界条件列清楚让人拍板时手里有选择余地。这比扔一个冷冰冰的最优值管用得多。
返回列表