双层优化驱动的配电网分布式光伏与储能选址定容

📅 发布时间:2026/10/13 8:14:31
双层优化驱动的配电网分布式光伏与储能选址定容
先说说这个项目到底在解决什么问题。配电网里接入分布式光伏和储能很多人第一反应是“找块空地装上就行”。但实际做规划的时候光伏板装在哪个节点、装多大容量储能柜放在哪、配多少容量这组决策会直接影响整条馈线的电压质量、网络损耗和投资回报。做得不对可能出现末端电压越限也可能出现白天光伏大发时功率反送顶到变压器容量上限。这个项目的核心就两件事选址和定容。位置不能随便挑容量不能拍脑袋需要一个数学模型把投资决策和运行调度统一起来考虑。我们选择用双层优化来做外层决定“在哪建、建多大”内层在给定配置下做最优运行调度通过迭代找到综合成本最低、电压改善最明显的方案。本文把整套思路、数学模型和Matlab实现过程拆开讲清楚适合配电自动化、微电网规划、新能源消纳方向的工程师和研究生参考也适合想上手智能优化算法解决实际工程问题的人。1. 项目到底在做什么选址定容方案的核心拆解1.1 选址定容为什么难不懂潮流计算很难拍板先说个基本概念。配电网不是一根线直接连到用户而是“树干式”的辐射状网络从变电站出来后分成一条条馈线沿线的节点不断挂接负荷。这种结构决定了越靠近线路末端电压跌落越严重。光伏和储能接在哪个节点会改变该节点及上游的潮流分布。如果光伏装在重负荷区域附近就地削减了馈线传输功率网损下降明显如果装在轻载线路末端中午光伏大发时多余功率顺着线路向变电站倒送末端电压会被顶高甚至超上限。实际规划中常见的两个误区一是按“哪负荷大装哪”的经验法不考虑光伏出力和负荷曲线的时间匹配二是只做容量校核不跑全年8760小时时序仿真结果投运后储能利用率低、电压问题照样存在。选址定容本质是一个高维组合优化问题节点数量多、候选方案爆炸人工靠经验只能覆盖少数场景必须用模型跑优化。1.2 为什么选双层优化两层决策的视角差异我一开始也考虑过把所有决策变量直接堆一个单层模型里求解后来发现工程上很难用。原因是这里天然存在两个决策层次时间尺度和决策属性完全不同。外层是投资层管的是“是否在某节点安装光伏、储能装多大”决策变量包含0/1整数变量和容量连续变量目标是全年综合成本最小以年为时间尺度。内层是运行层管的是“在给定配置下储能什么时候充、什么时候放、从主网购多少电”决策变量是连续的时间序列以小时甚至15分钟为时间尺度目标是日运行成本最小。把这两层拧成一个单层模型最大的问题就是变量类型混杂、维度巨大非线性强通用求解器要么解法慢要么经常找不到可行解。而双层优化在结构上更符合真实工程决策流程先定规划方案再做运行校验运行结果反过来反馈给规划层。这个“方案-运行-反馈”的闭环正是双层优化的核心价值。单层和双层之间的取舍实际做过实验后我的感受是这样的对比项单层集成优化双层优化建模难度变量多约束耦合复杂上层管投资下层管运行边界清晰可解释性黑盒求解难解释方案逻辑每一层目标明确方便定位问题求解效率大规模MIP求解慢外层启发式内层小规模优化工程可行全局最优性理论上可求全局最优启发式算法不保证全局最优但工程实用1.3 双层模型怎么理解一个贴近生活的类比把配电网想象成一个小区的物业管理。外层决策相当于开发商在建小区时决定要在哪个位置建停车场、建多大要不要装充电桩、装几个。这会花一笔建设费定了之后很难改。内层决策相当于物业每天调度白天充电桩怎么分配、停车场出入口怎么控制让每天运营成本最低。开发商在做决策时必须预估这个配置下未来每天的运营要花多少钱如果停车场建在很偏远的地方住户不愿意去运营亏损那这个配置就不划算。双层优化的逻辑完全一致上层每出一个配置方案下层就跑一遍最优运行把运行费用返回给上层上层据此评估这个方案的总账。理解了这一层很多细节就走通了。2. 双层优化模型怎么搭建数学公式与参数逐行讲清2.1 上层模型投资决策层怎么定义目标函数上层模型要回答的是“装不装、装在哪、装多大”。目标函数通常写成综合年费用最小包括三块年化投资成本、年运行维护成本、下层返回的年运行成本。年化投资成本不是把总投资直接除以年限那么简单要考虑资金的时间价值。常用的做法是用等年值法把初投资按折现率折算到寿命期内的每一年。公式大致是[ C_{inv} \sum_{i \in \Phi_{pv}} c_{pv} P_{pv,i} \cdot \frac{r(1r)^{N_{pv}}}{(1r)^{N_{pv}}-1} \sum_{j \in \Phi_{bess}} (c_e E_{bess,j} c_p P_{bess,j}) \cdot \frac{r(1r)^{N_{bess}}}{(1r)^{N_{bess}}-1} ]其中 ( r ) 是折现率( N ) 是设备寿命年限( c ) 是单位容量成本。比如光伏组件寿命通常取20年储能电池循环寿命对应年限通常取10年左右这组参数直接影响最优容量真算的时候要查最新的设备报价。上层约束比较直接每个候选节点光伏安装容量不超过该节点的可安装面积上限储能功率和容量要在可选档位内全系统总投资不超过预算。还有一类约束容易被忽略——同一节点如果同时装光伏和储能那么光伏板占地面积和储能柜占地要同时满足实际项目中需要折算出空间约束加入模型。2.2 下层模型运行调度层如何刻画储能行为下层模型在每个典型日下求运行成本最小。之所以选“典型日”是因为直接跑全年8760小时会让双层迭代的计算量爆炸。工程上通常把一年聚类成几个典型日比如夏季大晴天、冬季阴天、过渡季大风天每个典型日有典型的光伏出力曲线和负荷曲线再按天数加权折算回全年成本。下层的目标函数可以写成[ \min ; \sum_{t1}^{24} ( c_{buy,t} P_{grid,t} \Delta t - c_{sell,t} P_{sell,t} \Delta t \lambda_{loss} P_{loss,t} ) ]其中 ( P_{grid,t} ) 是主网购电功率( P_{sell,t} ) 是余电上网功率( \lambda_{loss} ) 网损惩罚系数。把网损放进去很重要因为选址定容一个主要目标就是降损如果下层只算购电成本会出现“虽然网损很高但买电便宜”的误导性方案。储能运行约束是下层模型的重头戏。SOC递推方程、充放电功率上下限、同一个时刻不能同时充放电、SOC不能越界这几条缺一不可。SOC递推写成[ SOC_{t1} SOC_t \frac{\eta_{ch} P_{ch,t} \Delta t}{E_{bess}} - \frac{P_{dis,t} \Delta t}{\eta_{dis} E_{bess}} ]充放电效率怎么选很关键。锂电池系统效率通常取0.9-0.95但要区分充进去和放出来两个方向写代码时最容易顺手把两个效率都设为0.92实际上应该按方向分别处理。另外还要考虑一个决策日内SOC初始值和终值是否相等。如果是“削峰填谷”的运行逻辑储能一天内完成一个充电放电循环通常约束初始SOC等于终态SOC如果考虑多日连续运行那就要研究时间窗的滚动问题。我用过的是等值约束代码实现简单结果也容易解释。潮流约束用DistFlow方程描述核心是节点有功/无功功率平衡、节点电压上下限、支路电流上限。配电网电压偏差通常控制在±7%以内即0.93到1.07标幺值光伏接入后重点盯末端电压是否越上限储能充电时能压住电压放电时会抬升电压这个特性决定了储能选址和光伏选址不能割裂考虑。2.3 上下层耦合关系数据怎么来回传递很多人第一次写双层模型卡住的地方是两层模型之间到底交换了什么数据上层传给下层的是光伏安装节点及容量、储能安装节点及功率/容量以及系统基础数据各节点负荷曲线、线路阻抗、光伏出力曲线。下层收到这份配置后求解储能充放电策略和从主网购电功率获得最小日运行成本把这个成本返回给上层。上层把这个运行成本乘上典型日天数权重折算回全年运行费用加到年化投资成本和运维成本上形成一个完整的适应度值。有个容易被忽略的细节下层除了返回运行成本通常还要返回电压越限惩罚费用、弃光惩罚费用。这两个量不仅影响目标函数值还能作为约束是否满足的指示器。如果某次配置导致某节点电压超过1.07潮流计算会得出严重越限这时候就不能只用“运行成本高”来惩罚它而应该单独加一个较大的惩罚因子让上层主动避开这个方案。3. Matlab代码实现流程从数据准备到求解器联调3.1 测试系统与数据准备一切从33节点开始我用的是经典的33节点辐射状配电网测试系统线路参数和负荷参数在很多公开资料里都能查到结构上是一条主干馈线带几条分支系统总负荷大概在3.7MW到4.5MW范围。选择这个系统做测试的原因有三个规模适中节点数量足够体现选址差异数据公开便于复现和对照它是典型的辐射状网络电压分布特征明显能清晰反映接入前后的变化。数据准备阶段要做的第一件事是形成系统导纳矩阵和线路连接关系。我习惯用两个矩阵存拓扑一个存线路首末端节点编号及阻抗一个存各节点基准负荷有功和无功。然后要准备时间序列数据至少包括24小时的负荷曲线和光伏出力曲线。负荷曲线参考典型居民和商业混合负荷形状光伏出力曲线根据当地日照条件取夏天大晴天形状最大出力出现在中午12点到14点之间。如果从零开始写建议先跑通一次不含储能的纯潮流计算验证电压分布和网损是否和公开数据一致。这一步是后面所有优化的基准如果基态潮流就有问题后面加什么算法都是错的。3.2 外层求解器选型粒子群为什么够用外层是选址定容的组合优化问题我选了粒子群算法PSO原因是工程上手快不需要求梯度对离散变量和连续变量的混合编码也能处理。遗传算法和差分进化也可以但我个人觉得PSO参数少、调参容易对这类中等规模问题够用。PSO的参数设置种群规模取30到50迭代次数取50到100。惯性权重从0.9线性递减到0.4这个策略能保证前期大范围探索、后期精细搜索。两个学习因子通常都取1.5左右。每个粒子就是一个候选配置方案位置向量由两部分拼接光伏候选节点集合的选址标志和容量、储能候选节点集合的选址标志和功率容量。这里要注意粒子更新后变量的整数性处理选址标志通过四舍五入取整容量连续变量如果超过上下限就截断。粒子群的每一次适应度评估都要调用一次完整的内层运行优化和潮流计算计算量集中在重复的时序潮流迭代上。为了提速我做了两个优化一是每个典型日只需跑一次储能调度优化和24个时段的潮流计算二是如果外层粒子给出的配置导致明显的电压越限可以先快速计算静态潮流预筛不合格的直接给一个大惩罚值省去完整的内层优化。3.3 内层求解策略储能调度怎么和潮流计算配合内层要做的是在给定配置下对多个典型日分别求储能24小时的充放电功率。最严谨的解法是用线性规划或二次规划直接求解因为目标函数和约束大多是线性的SOC递推是一个线性差分方程求解器很成熟。我在Matlab里直接用优化工具箱的线性规划函数变量维度不大24个时段两个方向的功率加SOC状态几十个变量而已一次求解很快。如果你没有优化工具箱也有替代方案用简化规则法。规则逻辑很简单光伏出力大于负荷且SOC未满时充电负荷大于光伏出力且SOC高于下限时放电其他情况由主网购电补足。规则法快但结果偏保守适合先跑通整个流程后期再替换成严格优化。我建议先用线性规划验证最优性规则法只做对照。内层优化返回的结果不只是购电成本还包括24个时段的储能SOC曲线和节点电压序列这些数据要留存在工作区里方便后面画图和分析。求解时有一个关键点储能设备的充放电效率不同充电功率和放电功率不能直接写成同一个变量乘效率需要拆成两个独立变量并加互斥约束。线性规划建模时用两个非负变量 ( P_{ch,t} ) 和 ( P_{dis,t} )然后加 ( P_{ch,t} P_{dis,t} \le M ) 防止同时充放这个约束一定要加。3.4 主循环伪代码把整个双层逻辑串起来下面给出简化版的主循环代码框架。这份代码体现了双层迭代的全部关键流程%% 主程序双层优化选址定容主循环 % 初始化 load(data_33node.mat); % 拓扑、负荷、光伏出力曲线 pop init_population(NP, dim, lb, ub); % 初始化粒子群 gbest_fitness inf; for iter 1 : MAX_ITER for i 1 : NP % 解码个体得到光伏选址/容量、储能选址/功率/容量 [pv_site, pv_cap, bess_site, bess_power, bess_cap] decode(pop(i,:)); % 可行性初筛容量越限、投资超预算直接惩罚 if check_feasible(pv_cap, bess_power, bess_cap) false cost_total 1e8; else % 调用下层运行调度函数内部含潮流计算 op_cost_sum 0; for d 1 : day_num op_cost_sum op_cost_sum day_weight(d) * ... run_operation(topology, load_curve{d}, pv_curve{d}, ... pv_site, pv_cap, bess_site, bess_power, bess_cap); end % 上层目标投资 运维 运行 inv_cost cal_invest(pv_cap, bess_power, bess_cap); om_cost cal_om(pv_cap, bess_power, bess_cap); cost_total inv_cost om_cost op_cost_sum; end % 更新个体最优和全局最优 if cost_total pbest_fitness(i) pbest_fitness(i) cost_total; pbest(i,:) pop(i,:); end if cost_total gbest_fitness gbest_fitness cost_total; gbest pop(i,:); end end % 更新粒子速度与位置 w 0.9 - 0.5 * iter / MAX_ITER; % 惯性权重递减 for i 1 : NP v(i,:) w * v(i,:) c1 * rand * (pbest(i,:) - pop(i,:)) ... c2 * rand * (gbest - pop(i,:)); pop(i,:) pop(i,:) v(i,:); pop(i,:) bound_check(pop(i,:), lb, ub); % 边界处理 pop(i,1:2:end) round(pop(i,1:2:end)); % 选址标志取整 end endrun_operation是内层核心函数内部完成三件事初始化储能SOC为0.2或按日循环约束调整、调用线性规划求解储能24小时出力、逐时段做潮流计算并统计网损电压。潮流计算采用前推回代法从根节点出发先假设各节点电压为标幺值1.0从末端往前推支路电流再往后代潮流求各节点电压反复迭代到电压偏差小于1e-6。前推回代法在这里足够可靠比牛顿拉夫逊简单而且辐射状网络下的收敛性有保证。3.5 潮流计算与储能SOC更新两个核心子函数潮流计算子函数里要注意光伏和储能接入方式。光伏在潮流计算里通常当恒定功率源处理输出有功无功按给定功率因数取0.95可设置。储能如果在充电状态等效为该节点有功负荷增加如果放电等效为有功出力。要注意的是潮流输入数据用的是标幺值所有功率要按系统基准容量转换至于基准功率取多少一般在初始化代码里统一设定。储能SOC更新的代码很短但容易错我贴一下自己常用的写法%% 储能SOC状态更新 soc zeros(T1, 1); soc(1) 0.2; % 初始SOC for t 1 : T % p_ch和p_dis是优化变量解出的时段功率kW soc(t1) soc(t) (eta_ch * p_ch(t) - p_dis(t) / eta_dis) * dt / cap_kwh; if soc(t1) 0.95 || soc(t1) 0.1 soc_penalty 1e6; % SOC越限大惩罚 end end % 日循环约束初始与末尾SOC相等 if abs(soc(T1) - 0.2) 0.01 soc_penalty soc_penalty 1e5 * abs(soc(T1) - 0.2); end这段代码的底层逻辑是SOC越限违反运行约束不能直接删掉这个变量而是通过惩罚函数把不可行解的成本抬高让外层粒子群自动“淘汰”这种配置。4. 调试心得与结果分析双层求解中踩过的坑全记录4.1 不收敛排查惩罚系数和变量缩放是重灾区第一类常见问题迭代30多代后适应度值还在大幅跳动没有收敛趋势。排查思路先看惩罚函数系数。如果容量越限或电压越限的惩罚系数只设成1e3而正常方案的总成本量级在1e6那惩罚几乎不起作用粒子群会频繁访问不可行区域。建议惩罚系数比正常目标值高1到2个数量级或者写成自适应形式迭代初期惩罚系数较小扩大搜索范围迭代后期惩罚系数增大逼迫粒子回到可行域。第二类常见问题粒子群速度更新后维度溢出。光伏容量和储能功率的量纲不一样如果直接把2MW的光伏容量和500kW·h的储能容量拼在同一个向量里PSO的速度更新会让数值波动集中在量纲大的维度上。建议统一归一化到[0,1]再优化或者分维度设置不同的速度上限。我的做法是编码时把容量全部除以各自的上限让所有维度都在0到1范围边界检查也更简单。第三类常见问题NaT或NaN传播。内层线性规划无解时目标函数返回NaN外层粒子群一旦更新到NaN全局最优解就废了。解决办法是在内层函数输出前检查优化状态无解时返回一个极大的有限值比如1e10而不是返回NaN。4.2 储能SOC不更新的典型错误效率方向弄反第一次写SOC递推时很多人写成soc soc eta_dis * p_dis * dt / cap把放电效率乘在了放电功率前。从电池实际行为来说充电时电网输入的电能经过变流器和电池内阻存入电池的能量等于输入能量乘充电效率放电时电池放出的能量经过变流器到负荷侧负荷侧得到的能量等于电池输出能量乘放电效率。所以递推公式里充电功率前乘 ( \eta_{ch} )放电功率前除 ( \eta_{dis} )两者方向不同写反了会导致SOC一天下来不升不降怎么调都不合理。还有个细节SOC上下限要不要给裕量我建议充电上限设0.95、放电下限设0.1不要设到1.0和0。因为线性规划解出的功率在离散时段边界处可能和SOC上下限刚好相等留裕量能避免数值边界抖动也让电池寿命评估更真实。4.3 双层迭代震荡外层的离散粒度太粗怎么办有时候粒子群迭代过程中最优方案会在两个候选节点之间反复跳变适应度值呈现周期性波动。这种震荡的本质是外层离散变量安装位置任意一个小变化会引起内层运行方案的大跳变导致目标函数曲面不光滑甚至不连续。处理办法有几个。第一个是给外层的候选安装位置做一个“邻域限制”每次粒子更新位置时只允许在距离上一代方案不超过两个候选节点的范围内寻优。这个限制等效于缩小搜索步长让粒子逐步逼近最优位置而不是全局乱跳。第二个方法是在粒子群更新中加入模拟退火接受准则以一定概率接受较差的解用温度参数控制收敛。第三个方法是修改内层模型在目标函数里加入“存输出功率和日前计划偏差”的惩罚项使内层结果对离散变化的敏感性降低。我实测下来邻域限制的效果最直接代价是搜索范围缩小会拖慢收敛需要多迭代一些代数来弥补。如果不希望在代码里增加复杂度也可以直接把最优解做二次局部搜索比如固定最优方案中的所有位置只对容量做精细连续优化这一步用matlab的fmincon做几十次迭代就够了。4.4 结果怎么看电压曲线和收敛曲线是关键指标跑完优化后我必画的三张图是基态与优化后的24小时电压分布对比图、粒子群收敛曲线、储能典型日SOC与充放电功率曲线。电压分布图能直观看出优化方案有没有真正解决末端电压偏低问题。以某次测试为例不接入光伏储能时馈线末端节点在晚高峰时段电压最低掉到0.931标幺值在最优配置下同一时段电压回升到0.972左右。白天的过电压问题也在可控范围内最高电压出现在中午光伏大发时约1.045标幺值没有超过1.07限制。收敛曲线主要看外层是否稳定下降。如果曲线前20代快速下降、后面30代缓慢平滑说明算法搜索过程正常。如果后面仍有明显的周期性上跳就要怀疑是不是惩罚系数不够或者粒子多样性过高。储能SOC曲线检查有两个重点一是SOC是否总在0.1到0.95区间内二是典型地下水储能是否呈现“白天充电、晚上放电”的规律。如果SOC曲线一整天都在0.2附近不动说明储能没有被有效利用运行优化模型可能有约束过紧的问题比如初始等于终值的约束堵死了日内充放电空间。4.5 常见问题速查表现象可能原因处理建议迭代后期仍剧烈波动惩罚系数过小或随机性太大增大惩罚系数到目标值量级的100倍以上最优解总是装在最贵节点缺少可控位置的资源限制约束检查候选集合是否覆盖了实际可安装节点储能优化结果总是满充满放未设置循环寿命或SOC限值设置SOC上下限同时评估充放电循环次数网损计算为0潮流计算未结合储能出力更新节点注入功率检查节点注入功率向量是否在每时段更新收敛速度快但解质量差粒子群过早陷入局部最优增大初始种群、用线性递减惯性权重的上限提高探索内层线性规划频繁无解储能容量太小或SOC初值设置不合理缩小SOC约束范围、检查初始SOC是否可行5. 扩展方向多目标、不确定性和工程落地细节5.1 从单目标到多目标成本和电压质量怎么平衡本项目的目标函数定的是综合成本最小实际工程中往往还要同时看电压偏差和供电可靠性。比如某几个节点电压偏低但改善电压要增加储能配置成本上升。这时可以用多目标粒子群把“年综合成本”和“平均电压偏移率”作为两个目标得到一组Pareto前沿再按决策者偏好选方案。代码层面的改动不大只需要将适应度返回为两个值然后外层的非支配排序逻辑替换原来的单目标比较。对研究生来说这个方向很适合作为扩展章节写进论文把目标从成本单目标扩展为成本、电压偏差、网损多目标再加上TOPSIS或熵权法选出一个折中最优方案。Matlab里用多目标粒子群实现的代码量不大效果却很有说服力。5.2 考虑光伏出力和负荷的不确定性光伏出力受天气影响大负荷也有随机波动。如果把典型日的出力看作确定性输入算出来的最优容量往往偏乐观实际运行中可能出现弃光或供电紧张。工程上的处理思路是把光伏出力场景从确定性曲线改成多场景集合晴天、多云、阴天各生成概率每个场景单独跑下层优化运行总成本按场景概率加权求和。还有一种更严谨的做法是引入机会约束规划让电压越限或功率倒送的概率在某个置信水平以内。从代码实现角度场景法改动起来最直接定义场景结构体数组循环调用内层运行函数最后加权求和。需要注意的是场景数不要太多否则外层粒子群每次评估的耗时成倍增长。我建议选3到5个代表性场景再多就要考虑降低潮流计算频率或采用代理模型。5.3 实际工程中要注意的落地细节论文里最优配置和实际施工之间还有一段距离。第一候选安装节点要考实际屋顶面积或场地条件不是所有节点都允许建设。第二光模型算出来的是理想利用率实际运行中要考虑光伏逆变器容载比、储能电池衰减特性、温度对SOC估算的影响。第三并网接入方案需要校核保护配合这已经超出优化模型范围有条件的话要把优化结果拿到真实配电仿真平台里做电磁暂态验证。代码层面给一点实用建议把所有常量参数集中放一个params.m脚本里包括折现率、寿命、设备单价、效率、SOC上下限、惩罚系数。因为后期调参大概率是全项目最频繁的操作散落在各处的话改起来痛苦不说还容易改漏。另外建议把每次优化结果自动保存到文件包括目标值、选址表和典型日曲线方便离线分析和画图比较。我自己就是在调完一次参数后把结果存成结构体然后直接一键画出全部对比图省去每次重跑优化。这个项目的核心价值在于用一套清晰的数学框架回答了“分布式能源到底该装在哪”这个工程决策问题同时把投资计划和运行策略统一到同一个优化循环里。如果有读者刚起步做类似方向我建议不要一上来就追求算法复杂度先把基础潮流和单目标双层流程跑通拿到正确电压分布和成本数据再逐步加入多目标和不确定性。代码调试过程中多看电压曲线和SOC曲线这两条曲线会告诉你模型哪里不合理比盯着目标函数数值靠谱得多。