资讯动态

冷热电多微网与储能电站双层优化配置的Matlab实现

发布时间:2026/9/10 17:08:34 来源:尧图企业网站定制
从去年开始前前后后帮几个做综合能源规划的朋友看过储能电站与微网结合的优化项目大家聊得最多的不是某一个求解器有多强而是“多微网之间到底怎么联动”“储能电站服务怎么定价/算收益”“容量配置和运行调度先算哪个”。这些问题落到底层都会聚到一个题目上来冷热电多微网系统的双层优化配置。这个方向在Matlab里做工程落地是目前很多课题组和设计院都在用的路线。这篇文章我就从问题建模、双层框架、Matlab代码实现、仿真结果到实际踩坑完整走一遍适合正在做毕业设计、科研仿真或者工程预可研的读者参考。先说清楚一个容易被绕晕的点冷热电多微网不是一套系统而是若干套含冷、热、电三种负荷的能源子系统通过公共联络线和共享储能电站连在一起。优化配置要解决两个不同时间尺度的问题——第一是未来十年或二十年储能电站和各微网的关键设备容量到底建多大第二是每一天面对给定的容量和负荷曲线机组、储能、购售电怎么调度。两个问题叠在一起互相影响这就是“双层”的由来。1. 先理清楚冷热电多微网、储能电站和双层优化分别要做的事1.1 冷热电多微网怎么搭起来的传统意义上的微网通常只考虑电负荷外加一个燃气轮机或光伏配储能就可以跑起来。但是综合能源系统一旦加上冷负荷和热负荷问题就会复杂不少。冷热电多微网里每一个子微网内部通常包含几个核心供能单元供电侧光伏PV、风力发电机WT、燃气轮机GT或者燃气内燃机必要时从上级电网购电。供热侧燃气轮机余热回收装置、燃气锅炉GB、热泵可选再加上蓄热罐。供冷侧电制冷机EC、溴化锂吸收式制冷机AC利用余热驱动有条件时配蓄冷罐。储能侧电池储能系统BESS在“储能电站服务”这个主题下它往往不是单一微网内部的而是多个微网共享的一个集中式储能电站。多个微网之间通过联络线在电力层面互联冷、热负荷一般只在微网内部平衡因为冷热介质远距离输送损耗大工程上很少跨微网交易。论文或项目里常说的“多微网协同”绝大多数指的是电力的共享和储能服务的共享。1.2 储能电站“服务”与容量属性的两副面孔储能电站在这个题目里是一个很有意思的角色它既是被配置的对象又是提供运行服务的载体。作为被配置对象我们需要决策储能的额定功率和额定容量这是“投资层”的变量。储能电站可以看成是一个集中式电站服务于多个微网而不是每个微网各建各的储能。集中式布局可以减少冗余投资尤其在用地紧张或消防审批比较严格的园区场景下共享储能是常见做法。作为服务提供者在实际运行中储能电站要参与多个微网的电力平衡。它可以给微网A充电、给微网B放电也可以作为备用容量平抑风光波动。这些运行行为直接影响储能SOC荷电状态的曲线进而反馈到运行成本里。建模时要注意储能电站的收益来源有两种口径一种是储能电站在电网侧赚取峰谷价差和需求响应服务费微网系统支付服务费另一种是把储能电站当作微网群共有的资产收益直接体现在减少购电成本和弃风弃光惩罚里。两种口径会影响上层目标函数的写法做Matlab代码前一定先确定好经济口径不然后面所有结果都不对。1.3 为什么必须用双层而不是一个大模型一锅炖很多初学者会问既然容量和运行之间有耦合为什么不把所有决策变量放进一个混合整数线性规划里一起求解理论上可以实际非常难。原因有三个时间尺度跨度太大。容量变量的寿命周期是10到20年运行变量是每小时甚至15分钟一个。直接建一个8760小时的全年优化模型变量数量会膨胀到几十万甚至上百万很多MILP求解器根本扛不住。非线性关系不好处理。投资成本与容量之间是非线性函数运行成本与调度决策之间又牵扯机组启停等整数变量两者强耦合直接用单层模型很容易陷入维数灾。工程上需要分别考察规划和运行两个阶段。规划人员关心投资边界运行人员关心调度规则双层架构更像实际项目中的“先定方案、再定运行方式”流程。所以目前主流做法是外层用智能优化算法遗传算法、粒子群等搜索容量方案内层用数学规划精确求解给定容量下的最优运行方案。外层每产生一个容量方案内层就运行一次把运行成本返回给外层的适应度函数。这就是“双层嵌套”的经典实现。2. 设备建模与能量平衡优化模型的物理底子2.1 供给侧设备光伏、风机、燃气轮机的出功特性在Matlab里做双层优化设备模型不能太粗糙也不能精确到电磁暂态那是电磁仿真软件的事。优化模型里常用的是稳态效率模型和出力上下限约束。光伏出力只和光照强度相关一般用 (P_{PV,t}P_{PV,rated}\times \frac{G_t}{G_{ref}}\times \eta_{PV}) 折算其中 (G_{ref}) 是标准光照强度1000 W/m²。在Matlab中直接读入小时级光照数据即可。风机出力是风速的分段函数切入风速、额定风速、切出风速三个参数定下来就能得到每个时间点的出力上限。燃气轮机核心在于“热电比”的概念。燃气轮机发电的同时会产生余热余热可以通过换热装置供采暖或送入溴化锂机组制冷。它的发电功率和热回收功率之间存在耦合(H_{GT,t} \alpha_{GT} \cdot P_{GT,t})其中 (\alpha_{GT}) 是热电比通常取1.01.5之间。这个耦合关系直接影响下层调度的灵活性。这里我在实际项目中遇到最容易被忽略的点是燃气轮机不是想发多少电就发多少电的它有一个最小技术出力。比如某型号燃气轮机额定功率5MW但低于30%负载时效率陡降甚至无法稳定运行。所以约束里必须加 (P_{GT,min}\cdot u_{GT,t} \le P_{GT,t} \le P_{GT,max}\cdot u_{GT,t}) (u_{GT,t}) 是二进制启停变量。2.2 冷热负荷侧溴化锂机组、电制冷机、燃气锅炉怎么配合冷热负荷的平衡是冷热电三联供系统里相对繁琐的一环因为你面对的不只是一个单一能量而是一条能量转换链。燃气轮机余热除了直接供热还可以驱动溴化锂吸收式制冷机。溴化锂机组制冷输入是热能输出是冷能有自身的制冷系数COP_ac一般0.7左右。这里要注意虽然叫“吸收式制冷”它能同时提供冷水和热水热回收但在小规模微网里通常按供给冷负荷为主、回收余热为辅来建模。电制冷机EC是补充制冷手段输入电、输出冷COP_ec一般为35效率高但贵在耗电。溴化锂机组的优势是“不花钱的热”换成“省钱的冷”前提是燃气轮机在运行且有余热可回收。燃气锅炉GB则是最灵活的补热手段效率一般0.850.95模型简单(H_{GB,t} \eta_{GB}\cdot F_{GB,t})其中燃料量 (F) 决定输入热量。真正的难点在冷热电联供的“联”字上燃气轮机发出电、回收热热既可以供暖也可以制冷。所以在同一时刻热负荷平衡方程里要有余热回收 燃气锅炉产热 蓄热罐放热 采暖热负荷 溴化锂机组消耗热。冷负荷平衡方程里要有溴化锂机组产冷 电制冷机产冷 蓄冷罐放冷 冷负荷。这两个方程必须分季节写因为夏季冷负荷大、热负荷小热几乎全用于驱动溴化锂机组冬季热负荷大、不需要太多冷过渡季节冷热负荷都不大燃气轮机的运行策略又会不同。这也是为什么下层优化通常要做多个典型日场景而不是只做一个24小时模型。2.3 储能设备的状态约束与使用寿命储能电站的建模比普通设备更有讲究因为它是“跨时段链接”的能量运行桥梁。核心约束是SOC递推方程[ SOC_{t1} SOC_t \eta_c \cdot \frac{P_{ch,t}\cdot \Delta t}{E_{rated}} - \frac{P_{dis,t}\cdot \Delta t}{\eta_d\cdot E_{rated}} ]其中 (SOC_t) 是t时刻荷电状态(\eta_c)、(\eta_d) 是充放电效率(E_{rated}) 是额定容量。约束还需要加入SOC上下限通常0.10.9避免过充过放。充放电功率上下限由额定功率决定。同一时刻不能同时充电和放电这一步在YALMIP里用二进制变量实现也可以写成 (P_{ch}\cdot P_{dis}0) 的互补约束但互补约束非线性推荐直接用二进制变量做MILP。日始日终SOC相等用于模拟多典型日的周期性。如果每个典型日独立计算这个约束很关键否则储能会在每个典型日结束时把能量全部放空导致结果失真。使用寿命问题通常不直接写进约束而是在上层目标函数中考虑储能寿命损耗成本比如按照循环次数折算到每次运行成本里。如果忽略这一点下层优化会倾向于过度使用储能得到偏低的运行成本。2.4 多微网互联与主网购售电的交互边界多微网系统的核心假设是各微网可以通过公共联络线交换电力。互联越强系统调度的灵活性越好但相应地网络潮流约束和联络线容量约束也越复杂。在优化模型里通常简化处理为一个互联功率约束[ P_{line,k,t} \le P_{line,k,max},\quad \forall k,t ]以及每个微网的平衡方程中增加交换功率项 (P_{ex,i,t})。当微网i向微网j输送功率时(P_{ex,i,t}0)接收端对应减去。为了建模方便一般要求所有微网的交换功率之和为零或者将交换功率接入公共母线。对于储能电站它一般也接到公共母线上可以同时跟任意一个微网交换功率。这个结构在Matlab里用矩阵或者cell数组管理多微网数据比写一堆“硬编码”要清晰得多。另外从上级电网购电一般设置分时电价售电价格低于购电价格。在双层模型中这是一个很重要的经济运行信号。实际代码里可以直接用一组电价向量结合各微网的交换功率来计算购电成本。3. 双层优化配置模型上层定容量下层排运行3.1 上层模型投资成本最小化的决策变量与目标函数上层模型是规划问题的承载者。我先给出最通用的写法决策变量储能电站额定功率 (P_{BESS,rated})、额定容量 (E_{BESS,rated})。各微网的燃气轮机额定容量 (P_{GT,i}^{cap})、光伏容量 (P_{PV,i}^{cap})、风机容量 (P_{WT,i}^{cap})。制冷/制热设备的额定容量如溴化锂机组容量 (Q_{AC,i}^{cap})、电制冷机容量 (Q_{EC,i}^{cap})、燃气锅炉容量 (Q_{GB,i}^{cap})。联络线容量等。目标函数[ \min ; C_{inv} C_{ope} ]其中 (C_{inv}) 是等年值投资成本需要将设备初始投资按寿命年限和折现率折算成年值[ C_{inv} \sum_{k} CRF_k \cdot c_k^{inv} \cdot S_k^{cap} ]CRF是等额分付资本回收系数(CRF \frac{r(1r)^L}{(1r)^L-1})r是折现率L是设备寿命。这个公式看起来简单但很多初学代码的同学会漏掉导致投资成本被高估好几倍。比如一套储能系统寿命10年折现率8%CRF算出来约0.149如果直接把初始投资成本全部加进去而不做年值化上层优化会严重偏向“不建储能”。运行成本 (C_{ope}) 是由下层返回的。在多典型日场景下它是各个典型日运行成本乘以全年天数加权求和的结果[ C_{ope} \sum_{s1}^{S} w_s \cdot N_s \cdot C_{ope,s}^{day} ]其中 (w_s) 是场景权重(N_s) 是一年中该类典型日的天数。3.2 下层模型典型日运行成本最小的调度问题给定上层的容量方案后下层针对每个典型日、每个微网做24小时优化调度。目标函数为[ \min ; C_{fuel} C_{grid,buy} - R_{grid,sell} - R_{service} C_{penalty} ]具体项拆开来看(C_{fuel})燃气轮机和燃气锅炉消耗天然气费用。(C_{grid,buy})从主网购电费用按分时电价计算。(R_{grid,sell})向主网售电收入如果允许余电上网。(R_{service})储能电站向微网提供调节服务的收益根据约定的服务费率计算在共享储能模式下。(C_{penalty})弃风弃光惩罚、负荷失负荷惩罚。通常取一个较高系数目的是避免优化结果出现无法满足负荷平衡时直接砍负荷。下层模型的约束我在第2章基本都列出来了包括能量平衡约束、设备出力上下限、储能SOC递推、燃气轮机启停约束、联络线功率约束等。对于多微网系统每个微网的决策变量可以写成矩阵形式在Matlab中用sdpvar定义对应维度的变量约束同样用循环批量添加。3.3 上下层之间的信息传递与迭代逻辑双层模型的信息流可以总结成一句话上层输出容量方案给下层当下层模型参数下层把最优运行成本和调度结果返回给上层作为外层的适应度评价。这个迭代关系在数学上可以表述为[ \min_{X^{cap}} F(X^{cap}, \phi(X^{cap}))\ s.t.; X^{cap} \in \Omega_{cap} ]其中 (\phi(X^{cap})) 是内层优化问题的最优值函数[ \phi(X^{cap}) \min_{X^{op}} f(X^{op})\ s.t.; g(X^{op}, X^{cap}) \le 0 ]也许有读者会问能不能直接用一个目标函数嵌套内层约束来构建单层模型可以但那需要利用KKT条件将下层模型等价替换成上层模型的约束形成所谓的“数学规划带均衡约束”问题。这个做法的优点是不用反复迭代求解精度有保证但它的实现难度很高尤其下层模型带二进制变量时KKT等价替换会非常复杂。所以工程上更常见的是用启发式算法嵌套MILP的迭代方法。从实际效果看只要外层种群规模和迭代次数足够优化结果在5%以内的偏差通常是可以接受的。4. Matlab代码实现内外层求解器的选择与衔接4.1 求解算法选型为什么外层用遗传算法内层用数学规划双层嵌套求解框架里最关键的是内层模型要“又好又快”地精确求解外层模型要“又稳又准”地搜索容量解空间。内层本质上是一个混合整数线性规划问题因为燃气轮机的启停变量、储能充放电状态变量都是0/1整数。用Matlab自带的intlinprog可以解但冷热电联供系统里变量多、约束多intlinprog在大型问题上稳定性一般速度也不够理想。我推荐用YALMIP建模然后调用CPLEX或Gurobi求解器。YALMIP的好处是建模代码非常简洁不容易出错而且换求解器只需要改一行设置。外层则是一个非线性、非凸、有约束的组合优化问题而且适应度函数本身就是一个优化问题的最优值。这种情况下采用遗传算法效果稳定而且Matlab的Global Optimization Toolbox自带ga函数简单配置就能跑通。为什么不外层也用内层一样精确求解因为外层目标函数内含一个子问题通常不可导、非凸甚至没有解析表达式商业求解器面对“黑箱函数”无能为力。因此外层只能靠无导数优化方法。4.2 用YALMIPCPLEX搭建内层优化模型内层模型的代码结构我一般写成一个独立函数innerOpt输入是容量参数和场景数据输出是运行成本和调度结果。这样可以方便外层重复调用也方便单独测试内层模型。先看内层模型的主函数框架伪代码但接近实际可改function [opCost, result] innerOpt(cap, data) % 读取容量参数 Pgt_cap cap.Pgt_cap; Ppv_cap cap.Ppv_cap; Pbess_p cap.Pbess_p; Ebess cap.Ebess; % 定义决策变量 nt 24; Pgt sdpvar(nt, 1); % 燃气轮机出力 ugt binvar(nt, 1); % 燃气轮机启停 Ppv sdpvar(nt, 1); % 光伏出力 Pch sdpvar(nt, 1); % 储充电功率 Pdis sdpvar(nt, 1); % 储放电功率 uBess binvar(nt, 1); % 储能充电状态1 Pbuy sdpvar(nt, 1); % 购电功率 Psell sdpvar(nt, 1); % 售电功率 Hgb sdpvar(nt, 1); % 燃气锅炉产热 Pec sdpvar(nt, 1); % 电制冷机功率 Qac sdpvar(nt, 1); % 溴化锂制冷量 Soc sdpvar(nt1, 1); % SOC长度1方便写初值 % 约束集合 C []; C [C, 0 Pgt Pgt_cap]; C [C, Pgt Pgt_cap * ugt]; % 启停约束 C [C, Pgt Pgt_cap * 0.3 * ugt];% 最小技术出力 % ... 设备上下限约束、能量平衡约束、SOC递推 ... % 目标函数 Objective sum(fuel_price .* (Pgt / eta_gt Hgb / eta_gb)) ... sum(price_buy .* Pbuy) ... - sum(price_sell .* Psell); % 求解 ops sdpsettings(solver, cplex, verbose, 0); optimize(C, Objective, ops); opCost value(Objective); result.Pgt value(Pgt); result.Soc value(Soc); % ... end用binvar定义二进制变量后YALMIP会自动把问题识别为MILP并交给CPLEX求解。这个函数内层要解决的MILP规模不算大一般几百个二进制变量CPLEX几秒内能解完一层所以外层即便跑50代、60个种群总耗时也能控制在可接受范围。4.3 外层调用内层的代码骨架外层用Matlab遗传算法工具箱。关键点在于编写适应度函数把“容量决策”解码成设备容量再去调用内层优化。function fitness outerFitness(x, scenario) % x是染色体向量按顺序编码各设备容量 cap.Pgt_cap x(1); cap.Ppv_cap x(2); cap.Pbess_p x(3); cap.Ebess x(4); % ... % 计算年投资成本等年值 invCost calcAnnualInv(cap); % 遍历多个典型日调用内层求解运行成本 opCost 0; for s 1:length(scenario) [dailyCost, ~] innerOpt(cap, scenario(s)); opCost opCost scenario(s).days * dailyCost; end % 加惩罚项保证约束满足 fitness invCost opCost penalty(cap); end主程序调用nvars 6; % 根据决策变量数调整 lb [0.5, 0, 0.5, 2, ...]; % 下限 ub [10, 20, 5, 20, ...]; % 上限 opts optimoptions(ga, PopulationSize, 40, MaxGenerations, 50, ... Display, iter, UseParallel, true); [x_opt, fval] ga((x) outerFitness(x, scenario), nvars, [], [], [], [], lb, ub, [], opts);这里有个容易被忽略的坑遗传算法的lb和ub上下限如果设置太宽外层搜索空间巨大内层模型容易出现不可行解如果设置太窄又可能把最优方案排除在外。我的做法是先做一次初步容量估算或参考同类工程案例把上下限设定为“经验值±50%”的范围。4.4 初始化、约束处理与结果回传的细节这部分我吃了不少亏值得单独拿出来讲。初始种群不宜全随机。如果你对容量有粗略估计可以把初始种群中一部分个体设为基于启发式规则的方案比如按峰值负荷的0.3倍设电池功率然后把剩余个体随机化。这样遗传算法收敛速度会明显加快。具体做法是在调用ga前自定义初始种群InitialPopulationMatrix。内层模型返回结果后一定要检查求解状态。optimize函数会返回info.problem如果等于0说明求解成功等于1说明不可行等于2说明无界。在外层迭代中如果某个个体导致内层不可行不要直接给它一个大罚函数值那样会扭曲遗传算法的搜索方向最好返回一个很大的数如1e10让GA自然淘汰它。结果回传时注意数据类型。遗传算法传入的x是double但如果你在calcAnnualInv里用了矩阵点乘务必确认维度一致否则动不动就报矩阵维度错误。5. 仿真案例设计典型日数据、结果分析与方案对比5.1 算例参数与负荷数据下面用一个简化但结构完整的算例说明结果怎么分析。假设系统含3个微网各微网内部有光伏、燃气轮机共享1座储能电站。典型日设计为3个夏季典型日冷负荷高、冬季典型日热负荷高、过渡季典型日负荷水平低对应天数分别为120、120和125天合计365天。设备参数示例设备单位投资成本万元/MW效率/COP寿命年光伏3500.90逆变器效率20燃气轮机450发电效率0.35热电比1.220燃气锅炉800.9015电制冷机2004.015溴化锂机组2500.7015储能电池1200元/kWh 1500元/kW充放效率0.95/0.9510这里价格数据是工程常见值具体项目要按当地造价文件调整。折现率取8%。5.2 优化结果容量配置与运行方案在Matlab中把上述参数代入双层优化模型外层的遗传算法迭代50代后收敛最优容量配置大致趋势是光伏配置约为各微网年峰值电负荷的0.81.2倍。光伏单位投资相对低且白天出力与冷负荷高峰重合经济性最好。燃气轮机容量配置一般不会很大基本是“保底”思路满足夜间和连续阴雨天的供电。如果当地电价尖峰较高燃气轮机容量会适当上调。储能电站的功率容量比大致在24小时之间。也就是说如果额定功率10MW额定容量在20MWh40MWh之间。这个比值受峰谷价差影响很大峰谷价差越大储能系统越倾向于更长的容量时长。电制冷机配置大于溴化锂机组的情况在电价比天然气更便宜的地区比较明显反之天然气价格低而电价高的地区燃气轮机溴化锂组合更有经济性。这个规律在多个算例中非常稳定。下层运行调度的结果通常需要画几张图来体现储能的SOC曲线。好的调度结果显示SOC曲线一般呈现“谷段充电、峰段放电”的风格而不是频繁震荡。如果SOC曲线在一天内锯齿状波动说明目标函数中惩罚项权重设置不对或者储能寿命损耗成本没有纳入考虑。各微网的电力平衡图。把每个时刻的负荷、光伏出力、燃气轮机出力、储能充放电、联络线交换功率画成堆叠柱状图能一眼看出电量从哪里来、到哪里去。冷热电平衡图。检查夏季工况下溴化锂机组是否充分利用了燃气轮机余热冬季工况下燃气锅炉的产热量是否出现大面积浪费。5.3 敏感性分析储能价格和天然气价格的影响做优化配置不能只看一个方案还要做敏感性分析不然审稿人或评审专家很容易问“你的结论对价格波动稳不稳”。我的做法是固定其他参数单独扫描关键价格参数在Matlab里写一个二重循环storagePrice [800, 1000, 1200, 1500, 2000]; % 元/kWh gasPrice [2.0, 2.5, 3.0, 3.5, 4.0]; % 元/立方米 for i 1:length(storagePrice) for j 1:length(gasPrice) % 更新参数重新跑双层优化 [cap_opt(i,j), cost_total(i,j)] runBiLevelModel(storagePrice(i), gasPrice(j)); end end结果通常能看到这样几个规律储能单位投资下降50%最优储能容量上升幅度大约在30%60%而不是等比例翻倍。原因是储能容量增加到一定程度后边际效益递减再多配就变成“闲置资产”。天然气价格上升时燃气轮机最优容量下降光伏和储能容量上升。这说明多能互补系统对能源价格非常敏感优化配置结果不是固定的。如果某个典型日比如夏季冷负荷占比特别高最优方案里溴化锂机组容量会明显偏大因为余热制冷成本几乎可以忽略。6. 实测中的坑与调优经验6.1 内层模型不可行怎么排查这是Matlab双层优化里最常见的“劝退点”。明明单看每个约束都很合理但放到一起就不可行。我总结的排查顺序先不看双层单独用一组已知可行的容量值比如参考微网实际工程容量跑一次内层模型。如果这都不可行说明内层模型本身有矛盾。检查平衡方程的单位。最常见问题热量单位MWh制冷单位MW两者没有统一。还有自然气热值和电量的单位换算一个不留神就差了3倍。检查储能SOC递推的时间索引。如果SOC定义长度是nt1而约束中错误地使用了Soc(nt)和Soc(nt1)边界配置很容易写错。检查负荷数据是否出现负值。正常情况下负荷都是非负的如果从Excel读取时某列有缺失值或负值YALMIP不一定会报错但求解结果会非常离谱。6.2 外层遗传算法收敛慢的典型原因外层收敛慢绝大多数情况不是Matlab代码性能问题而是适应度函数地形太差。以下几个原因最常见内层求解时间太长。每个个体都要调用CPLEX如果内层MILP模型有几千个二进制变量单个求解需要几十秒40个种群跑50代就是几十个小时。解决办法是压缩典型日数量或者对微网做对称性简化也可以用并行计算UseParalleltrue这在多核机器上能节省约一半时间。自变量之间强相关。比如储能功率和储能容量本身就存在强耦合遗传算法往往会在这两个维度上反复震荡。我的办法是改变编码方式直接编码一个“储能容量时长”参数也就是 (E_{rated} / P_{rated}) 的比值然后在解码时根据功率计算容量这样搜索空间就坍缩了一维。惩罚函数设置不当。如果罚函数系数太大遗传算法会优先满足约束而放弃优化目标如果太小又会大量产生不可行解。我倾向于采用“不可行解直接返回大数”的策略而不是给一个渐进式惩罚简单有效。6.3 结果不“平滑”时怎么办有些时候外层经过多次迭代最优容量方案变化不大但总成本曲线仍然上下抖动而且每次跑出来的结果都不一样。这在内层含MILP的嵌套问题中很常见原因是内层MILP在某些参数临界点处最优解会发生跳变导致适应度函数不连续。应对方法增大遗传算法种群规模而不是单纯增加迭代代数。种群规模大更能抵抗适应度函数的噪声。对多个并行运行的结果取统计最优而不是只跑一次就下结论。我通常会跑35次独立优化取成本最低且容量配置相近的方案作为最终结果。如果项目对结果稳定性要求高可以考虑在遗传算法最后加入局部搜索比如以当前最优解为中心做小范围网格搜索验证是否还有更优解。6.4 给后来者的几条实用建议基于我这段时间反复调模型踩过的坑最后列几条足够实在的建议希望能帮读者少走弯路先把单微网、单典型日的模型跑通再扩展成多微网、多典型日。不要一上来就搭完整框架不然出问题根本没法定位。所有参数用结构体struct管理不要散落成一堆全局变量。尤其涉及多微网时用scenario(s).load_e(i,:)这样的结构比用load_e_i_s这种命名清晰得多。每改一次模型都要重新验证能量平衡。最简单的方法是在内层求解后手动把各设备的出力按平衡方程加一遍看残差是多少。如果残差超过1e-6说明模型有bug。保存好每个求解器和YALMIP的版本。不同版本的CPLEX和YALMIP之间偶尔会有兼容性问题同一个代码换台电脑可能就跑不了。养成写README记录环境的习惯非常有必要。储能电站服务费率的设定一定要和上层的投资回收逻辑闭环。如果共享储能电站的所有者是微网群本身服务费率只是一个内部结算参数不影响总成本如果储能电站是第三方投资那么服务费率必须满足其投资回收要求这会在上层模型中增加一个约束。两套经济口径千万别混着用。整个双层优化配置框架从建模到Matlab实现再到案例分析核心其实就一句话规划层做减法运行层做精细。只要把物理模型写清楚、求解器选对、数据处理好剩下的就是耐心调参。希望这篇文章能帮正在做冷热电多微网和储能电站课题的读者省掉一些自己摸索的时间。如果在实现过程中遇到具体问题也可以沿着本文的排查顺序逐层检查大概率能找到症结。

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价