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

资讯详情

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

多微网电能交互分布式优化:ADMM算法与碳排放协同调度实践

多微网电能交互分布式优化:ADMM算法与碳排放协同调度实践 做微电网能量管理这几年最深的体会是一个微网能做好不代表一群微网能做好。单微网问题本质上是一个“预测加优化”的问题预测光伏出力、预测负荷曲线然后滚动求解一个调度计划但多个微网放在一起之后多了一层硬约束——每个微网都是独立主体谁都不愿意把内部数据全部交出来。这时候ADMM这类分布式算法就成了绕不开的工具如果优化目标里再计入碳排放那么多微网间的电能交互策略就从一个单纯的经济调度问题变成了经济性与碳排放双目标协调的分布式优化问题。我最近完整跑了一遍“计及碳排放的多微网电能交互分布式运行策略”的Matlab实现把模型、ADMM迭代格式、代码结构、收敛性调参全链路走通了。如果你正准备做多微网分布式调度方向的研究或者刚接触ADMM想找个能落地的算例练手这篇内容应该对你有用。我会把数学建模怎么建、代码怎么分层、哪些参数最容易让人翻车、最后结果图怎么画才站得住脚一次讲清楚。1. 从单微网到多微网电能交互为什么必须用分布式算法1.1 集中式优化的数据壁垒和计算瓶颈最初我做微网优化也是“集中式思维”把所有微网的负荷预测、光伏预测、储能SOC、机组成本全部汇总到一个大模型里用求解器一次算完。单微网场景下这个思路完全可行目标函数、约束条件清清楚楚结果也是全局最优的。但到了多微网场景集中式就不好使了。第一层问题是数据壁垒。名义上各微网处在同一个园区或者同一个台区但实际运营时它们很可能分属不同利益主体。负荷曲线属于商业运行数据储能配置和成本参数属于运营机密没有义务向外部负责统一调度的中心节点公开。集中式优化要求所有微网把自己内部参数全部上报这个模式在工程上几乎无法落地。第二层问题是计算可扩展性。微网数量从三五个扩展到几十个之后模型维数和约束数量会快速增长。中心节点每收到一次数据更新就要重新求解整个全局问题如果某个微网的数据发生变化所有其他微网的计划都要跟着变实时性和可靠性都会出问题。这两个诉求叠加起来分布式协调就成为了必然选择每个微网内部自治地完成自己的优化计算只通过“交互功率”这个公共变量和中心协调层交换少量信息最终让整个系统的调度方案收敛到一个共同认可的状态。这里的核心逻辑不是“不想集中优化”而是“在真实系统里根本没法集中优化”。1.2 碳排放约束进入目标函数之后模型发生了什么变化现在的微电网调度不能只看经济账了。标题里的“计及碳排放”在研究里通常不是指建立一个复杂的碳排放流或者全生命周期评估模型而是把碳排放量折算成优化目标的一部分或者作为硬约束加进模型。常用的建模方式有三种。第一种是碳税/碳价机制。系统每从上级电网购买一度电就按照电网的平均碳排放因子折算成二氧化碳排放量再乘上一个碳价系数作为购电成本之外的附加项写进目标函数。本地如果有燃气轮机或者柴油机直接排放按照燃料的排放因子单独计算。第二种是配额机制。系统获得一定量的免费碳排放配额实际排放超过配额的部分需要按碳市场价购买如果实际排放低于配额富余的配额还可以出售获利。第三种最简单粗暴——直接给总碳排放量设一个上限把它作为不等式约束。实际做算例的时候这三种模式最好都做成可配置的选项方便做情景对比。值得注意的是碳排放不是简单地在目标函数里加一个线性项就结束了它会改变微网之间的交互策略。举个例子微网A午间光伏充裕但储能已经满了微网B刚好傍晚负荷高峰、储能容量充足。如果不考虑碳成本A可能倾向于把多余电量直接卖给配电网因为省事但计入碳成本后A和B之间的直接交互不需要经过上级电网也就规避了购电带来的间接碳排放综合成本更低。所以“计及碳排放”的约束会让微网间的电能交互变得更活跃这正是这类研究把“多微网电能交互”作为核心问题来做的原因。1.3 分布式算法虽多ADMM为什么成了默认选项分布式优化算法不止ADMM一种。比较常见的有基于一致性理论的一致性算法、对偶分解法、目标级联分析法ATC等等但它们在多微网电能交互场景下各有各的别扭。一致性算法的核心思路是让各微网像多智能体一样在通信网络上不断交换状态信息最终收敛到一致状态。实现简单、通信拓扑灵活但收敛速度和步长参数强相关调不好就发散或者收敛极慢。对偶分解法通过拉格朗日松弛把耦合约束解耦主问题更新乘子、子问题各自求解结构很清晰但它的收敛性依赖于原问题的凸性而且对多阶段耦合约束处理起来困难。目标级联分析法的收敛性依赖罚函数的更新规则参数选择不合适时同样容易振荡。ADMM本质上可以看作“带增广拉格朗日项的对偶分解”。它在拉格朗日乘子项之外额外加了一个交互功率的二次惩罚项。别小看这一项它让每次迭代都有了“平滑化”的效果显著改善了收敛稳定性。同时ADMM不需要复杂的通信拓扑一个单层中心协调结构就够了特别适合多微网这种“局部自治、全局协调”的问题结构。再加上这几年ADMM的理论分析已经非常成熟公开资料多、可参考的实现也多所以它在多微网论文里几乎成了默认算法。2. ADMM求解电能交互的数学模型迭代格式是怎么设计出来的2.1 目标函数与约束条件的形式化假设系统里有 (N) 个微网用集合 (\mathcal{I}{1,2,\ldots,N}) 表示。每个微网 (i) 的本地决策变量 (x_i) 包括(t) 时刻从上级电网购买的功率 (P_i^{\mathrm{buy}}(t))、向电网售出的功率 (P_i^{\mathrm{sell}}(t))、光伏出力 (P_i^{\mathrm{PV}}(t))、储能充电功率 (P_i^{\mathrm{ch}}(t))、放电功率 (P_i^{\mathrm{dis}}(t))以及与相邻微网 (j) 的交互功率 (P_{ij}(t))。每个微网的本地目标函数可以写成[ f_i(x_i) \sum_t \left[ C_{\mathrm{buy}}(t) P_i^{\mathrm{buy}}(t) - C_{\mathrm{sell}}(t) P_i^{\mathrm{sell}}(t) C_{\mathrm{CO}2} E_i(t) C{\mathrm{bat}}\left(P_i^{\mathrm{ch}}(t), P_i^{\mathrm{dis}}(t)\right) \right] ]其中 (C_{\mathrm{buy}})、(C_{\mathrm{sell}}) 是分时购售电价(C_{\mathrm{CO}2}) 是碳价(E_i(t)) 是 (t) 时刻折算的碳排放量(C{\mathrm{bat}}) 是储能充放电损耗成本。碳排放量由两部分构成本地燃气机组的直接排放加上从上级电网购电对应的间接排放[ E_i(t) \alpha_{\mathrm{grid}} P_i^{\mathrm{buy}}(t) \alpha_{\mathrm{diesel}} P_i^{\mathrm{diesel}}(t) ]其中 (\alpha_{\mathrm{grid}}) 是电网平均碳排放因子(\alpha_{\mathrm{diesel}}) 是本地燃料发电机组的排放因子。约束条件包括功率平衡约束、储能SOC递推约束和充放电上下限、购售电功率上下限、交互功率上下限等。这些约束全部留在各微网的子问题里中心协调层完全不碰这是分布式模型和集中式模型在结构上最本质的区别。2.2 增广拉格朗日分解与一致性变量多微网模型里系统层面唯一的物理耦合约束就是交互功率。对同一条交互线路微网 (i) 从微网 (j) 获得的功率必须等于微网 (j) 向微网 (i) 送出的功率方向相反[ P_{ij}(t) P_{ji}(t) 0 ]ADMM解决这个耦合约束的方法是引入一个公共的一致性变量 (z_{ij}(t))把约束等价改写为[ P_{ij}(t) z_{ij}(t), \qquad P_{ji}(t) -z_{ij}(t) ]这样一来每个微网的子问题里只包含自己的变量和公共变量 (z)微网之间的耦合被彻底解开了。这个“引入公共变量”的手法是整个ADMM分解的关键一步。写出增广拉格朗日函数[ L_\rho(x, z, \lambda) \sum_i f_i(x_i) \sum_{ij} \left[ \lambda_{ij}(P_{ij} - z_{ij}) \frac{\rho}{2} |P_{ij} - z_{ij}|_2^2 \right] ]这里 (\lambda_{ij}) 是对偶变量拉格朗日乘子(\rho) 是正数惩罚参数。后面那一项二次惩罚就是ADMM和普通对偶分解的差异所在。可以这么理解如果没有二次惩罚项各微网提出的交互功率计划差距很大时迭代会剧烈震荡加上二次惩罚项之后每次迭代都相当于在“坚持己见”和“跟随协调层意见”之间做了一个折中稳定性大幅提升。2.3 三步迭代子问题、全局协调、对偶更新有了增广拉格朗日函数ADMM的迭代就可以拆成三步。第一步各微网并行求解自己的子问题[ x_i^{k1} \arg\min_{x_i} ; f_i(x_i) \sum_j \left[ \lambda_{ij}^k (P_{ij} - z_{ij}^k) \frac{\rho}{2} |P_{ij} - z_{ij}^k|_2^2 \right] ]这个子问题只包含微网 (i) 的本地约束各微网之间没有数据依赖所以可以完全并行计算。这就是ADMM的“分布式”所在。第二步中心协调层收到各微网上报的交互功率计划后更新公共变量。假设微网 (i) 和微网 (j) 对同一断面的交互功率上报值分别为 (P_{ij}^{k1}) 和 (P_{ji}^{k1})由于两个值方向相反公共变量的更新公式为[ z_{ij}^{k1} \frac{P_{ij}^{k1} - P_{ji}^{k1}}{2} ]注意这里是差值的一半不是两个值的算术平均。如果 (P_{ij}) 和 (P_{ji}) 符号定义相反直接求平均会让 (z) 恒等于零公式就废了。这个细节很多第一次写代码的人会踩坑后面我会再强调。第三步更新对偶变量[ \lambda_{ij}^{k1} \lambda_{ij}^k \rho \left( P_{ij}^{k1} - z_{ij}^{k1} \right) ]然后重复三步直到原始残差 (|P - z|_2) 和对偶残差 (\rho|z^k - z^{k-1}|_2) 同时小于设定阈值。整个迭代过程里微网 (i) 不需要知道微网 (j) 的负荷曲线、储能SOC或者成本函数中心协调层也只需要汇总交互功率数据不关心微网内部模型隐私保护的逻辑就体现在这里。这个迭代思路可以类比成两个人协商一件共同事务各方先提出一个对自己最有利的方案然后在协商层取一个折中参考值再根据参考值和自己提报值的差距调整下一步的提报方案几个来回之后就达成一致了。3. Matlab代码实现从模型到可复现算例3.1 代码架构与文件划分这个项目的代码我强烈建议按“主脚本 子问题函数 全局更新函数 参数脚本”的方式组织。不要把所有逻辑一股脑塞进一个脚本里否则后面想换碳排放模式、换微网数量、想加网络潮流约束都会变成一场灾难。我跑通这套算例时用的文件划分如下文件名作用输入输出run_main.m主迭代循环调用其余函数绘制结果参数结构体迭代结果、收敛曲线、交互功率曲线set_parameters.m设置微网数量、日内时段、分时电价、碳价、负荷与光伏数据无参数结构体 paramssolve_subproblem.m求解单个微网在给定z和lambda下的本地优化问题微网编号、z、lambda、rho、paramsx_i、该微网上报的交互功率update_z.m中心协调层更新一致性变量所有P_inter、邻接关系zupdate_lambda.m对偶变量更新与残差统计P_inter、z、lambda、rholambda、primal_residual、dual_residual这个架构最大的好处是边界清晰想从一个微网扩展成五个微网只需改 set_parameters.m 里的邻接矩阵和数据想把碳排放从“碳税模式”改成“配额模式”只动 solve_subproblem.m 的目标函数部分想对比不同碳价的结果用循环改参数重跑主脚本就行。3.2 子问题求解与全局变量更新的核心代码子问题本质上是一个带线性约束的二次规划。为什么是二次规划因为目标函数里来自ADMM的惩罚项是交互功率的平方项天然自带二次型再加上购电成本如果按线性电价建模整个目标函数就是一个二次函数约束都是线性的。这种问题可以直接调用 Matlab 自带的 quadprog 求解不需要依赖任何第三方商业求解器对新手友好很多。核心代码示意如下节选关键部分function [x, P_inter] solve_subproblem(i, z, lambda, rho, params) % 读取参数 nT params.nT; P_load params.load(i, :); P_pv params.pv(i, :); P_buy_max params.buy_max(i, :); % 变量顺序P_buy(1..nT), P_sell(1..nT), % P_ch(1..nT), P_dis(1..nT), % P_inter(1..n_neighbor) n_var 3*nT params.n_neighbor; % 目标函数二次项来自ADMM惩罚项装配成 H 矩阵 H sparse(n_var, n_var); H(1:nT, 1:nT) rho * speye(nT); % 线性部分购电价格 碳成本 对偶变量相关项 f zeros(n_var, 1); f(1:nT) params.price_buy params.carbon_price * params.grid_factor; % 交互功率部分 for j 1:params.n_neighbor idx 2*nT j; f(idx) -lambda(j) - rho * z(idx); H(idx, idx) rho; end % 约束装配功率平衡、储能SOC、交互功率上下限等 % 完整实现按quadprog标准格式装配 A, b, Aeq, beq, lb, ub options optimoptions(quadprog, Display, off, ... OptimalityTolerance, 1e-8, ConstraintTolerance, 1e-8); x quadprog(H, f, A, b, Aeq, beq, lb, ub, [], options); % 从x中提取交互功率上报值 P_inter x(2*nT1 : 2*nT params.n_neighbor); end变量编排和约束装配部分如果读者直接照抄很容易在索引上翻车。我的建议是先跑一个2微网、1小时时段的极简算例把 H 矩阵、Aeq 矩阵的维度打印出来检查确认无误后再扩展到24时段和更多微网。矩阵维度错一行quadprog 返回 infeasible排查起来非常痛苦。全局更新部分要简单得多核心就是按前面说的差值公式更新function z_new update_z(P_inter_all, connect, nT) N size(P_inter_all, 1); z_new cell(N, 1); for i 1:N z_new{i} zeros(size(P_inter_all{i})); for j find(connect(i,:)) z_new{i} (P_inter_all{i} - P_inter_all{j}) / 2; end end end代码里需要为每个交互断面建立统一的编号映射比直接用二维矩阵存更清晰。如果接入的微网数量多了交互断面是稀疏的用邻接表遍历比全矩阵遍历效率高得多。3.3 算例参数设置与碳排放数据构造算例规模我建议从4个微网、24小时开始。四微网规模既能让交互关系丰富起来又不至于让调试复杂度失控。可以参考下面的参数框架参数参考值微网数量4时间分辨率1小时共24个时段各微网峰值负荷150 kW ~ 300 kW光伏装机50 kW ~ 200 kW各微网不同储能容量100 kWh ~ 300 kWh储能最大充放电功率30 kW ~ 60 kW购电价格峰时0.9元/kWh谷时0.35元/kWh售电价格峰时0.7元/kWh谷时0.25元/kWh电网碳排放因子0.57 kg CO2/kWh碳价50 元/吨可调交互功率上限50 kW负荷和光伏曲线不需要多复杂取典型的夏季或者冬季负荷形状叠加随机扰动就可以。光伏出力曲线用Beta分布生成或者直接用实际辐照数据拟合。重点在于让各微网的余缺特性拉开差异微网1光伏大、负荷小微网2光伏小、负荷重微网3储能容量大但本地发电不足微网4正好相反。如果所有微网的光伏负荷比例完全一样算出来的交互功率会趋近于零后面画出来的结果图毫无说服力。碳排放数据本身不用构造复杂的时间序列按电网碳排放因子换算即可。后面做敏感性分析时把碳价从0变化到300元/吨画出系统总碳排放量和总成本曲线这一张图基本就是论文里最核心的结果之一了。4. 收敛性调试与参数整定实践中的坑4.1 惩罚参数 rho 到底怎么调rho 是ADMM里最需要花心思调的量它的选择对收敛速度影响极大但对最终收敛值影响很小。rho 取得太小二次惩罚项对变量的牵制作用太弱各微网提交的交互功率计划差异很大中心协调层要很多轮才能把大家拉齐收敛很慢。rho 取得太大惩罚项在目标函数里占了主导地位各微网倒是很快在交互功率上达成一致了但本地成本函数的信息被显著压制对偶乘子的更新变得非常慢整体上照样收敛慢。经验上从 1 到 100 这个范围扫一遍通常能找到感觉。更稳妥的做法是让 rho 自适应变化如果当前原始残差明显大于对偶残差说明交互功率一致性还没有对齐就适当增加 rho如果对偶残差明显大于原始残差说明惩罚太重压制了对偶更新的节奏就适当减小 rho。Matlab 里每迭代几步检查一次残差比例动态更新 rho 即可。这个自适应策略在Boyd等人的ADMM综述里有推荐实际实现也很简单三五行代码的事。4.2 停止准则别只设迭代次数不少人为了省事直接设固定迭代次数或者“目标函数变化小于阈值”就停了。这个方法在工程验证阶段可以接受但放到论文里是站不住脚的审稿人一定会问“收敛判据是什么”。规范的停止准则是原始残差和对偶残差同时小于归一化阈值[ r^k |P^k - z^k|_2 ] [ s^k \rho |z^k - z^{k-1}|_2 ]阈值参考Boyd的建议用绝对容差和相对容差组合[ \epsilon_{\mathrm{pri}} \sqrt{M} \epsilon_{\mathrm{abs}} \epsilon_{\mathrm{rel}} \max(|P^k|2, |z^k|2) ] [ \epsilon{\mathrm{dual}} \sqrt{M} \epsilon{\mathrm{abs}} \epsilon_{\mathrm{rel}} \rho |\lambda^k|_2 ]其中 (M) 是耦合变量的总数(\epsilon_{\mathrm{abs}}) 通常取 (10^{-4})(\epsilon_{\mathrm{rel}}) 取 (10^{-3})。把这个判据写进迭代循环的跳出条件结果才有说服力。4.3 迭代振荡与不收敛的完整排查链路我调试时最常遇到的现象是交互功率在某个断面上来回振荡z 值在两三个数之间跳来跳去原始残差降不下去。这种问题排查是有固定顺序的不要一上来就怀疑模型建错了。第一看符号约定。这是最容易被忽略又最高频出错的点。代码里 (P_{ij}) 和 (P_{ji}) 方向定义是否一致z 更新时到底用“差值的一半”还是“算术平均”直接决定了公式对不对。如果这一步错了后面怎么调参数都白搭。第二看子问题可行性。某个微网如果本地约束过紧典型情况是储能容量太小晚上必须高价购电它上报的交互功率会一直顶在边界上导致整体收敛困难。这种情况可以在交互功率上限处加一个小的松弛变量观察残差是否明显下降。第三看约束装配的维度。quadprog 的 A 矩阵和 Aeq 矩阵行数必须和时段数严格对应多一行少一行都会产生不可行问题。可以通过打印每个子问题的退出状态定位是哪个微网不可行。第四如果确认模型和数据都没有问题那就是 rho 的锅做一次扫参实验把不同 rho 下达到停止准则的迭代次数画成曲线选一个迭代次数最少的点。这里分享一个沿用很久的调试技巧先跑1个时段的小规模问题验证ADMM三步迭代逻辑正确再扩展到24时段。直接把24时段全跑起来一旦不收敛很难判断是数据问题、索引问题还是算法逻辑问题基本等于盲人摸象。5. 算例结果怎么设计、怎么解读才有说服力5.1 三张必须画的结果图第一张是收敛曲线。横轴为迭代次数纵轴分别为目标总成本、原始残差和对偶残差。这张图要说明算法在有限迭代步内达到了稳定解。残差建议用对数坐标因为残差下降通常跨越多个数量级线性坐标下前面几轮就把曲线压扁了看不出细节总成本用普通坐标能看出系统目标在迭代中逐步下降并趋于平稳的过程。第二张是典型日各微网的交互功率计划。横轴为24小时画出各微网之间的交互功率曲线。从这张图可以直接读出电能交互的方向和时段特征午间光伏大发时交互功率大晚间负荷高峰时交互方向反转。如果各微网交互功率收敛得足够好曲线应该是平滑的曲线出现毛刺说明收敛精度不够或者 rho 需要再调整。第三张是碳价敏感性分析图。以碳价为横轴画出系统碳排放总量、总运行成本和总交互电量的变化曲线。这三条曲线放在一张图里既做了灵敏度分析也是整个“计及碳排放”研究意义的直观证明。碳价提高后系统碳排放总量下降、总成本上升、交互电量变化三个趋势可以用一个自然段解读清楚。5.2 与集中式最优解对比验证做分布式算法的研究绕不开一个指标和集中式最优解的差距。做法是把所有微网的参数汇总到一个全局优化模型里用同一个求解器直接求全局最优解然后对比两种方式的总成本和调度结果。ADMM收敛后的总成本和集中式最优解之间的相对间隙如果能控制在 0.5% 到 1% 以内就可以说明分布式算法没有显著牺牲最优性。这里有个容易被忽视的细节全局模型和ADMM子问题里的成本参数必须完全一致。我就遇到过两边参数口径不一致的情况——子问题里计入了碳税成本全局模型里却漏掉了结果两个总成本怎么都对不上排查了半天才发现是设定差异。先进性验证之前先做一次参数一致性检查能省下大量时间。对于非凸或者混合整数子问题ADMM的收敛只能保证到局部最优这时候对比集中式结果时要把这个前提说清楚不要硬把局部最优说成全局最优。5.3 碳价敏感性与情景设计建议最终的敏感性分析可以设置几个情景覆盖标题里“计及碳排放”的全部内涵情景A完全不考虑碳排放约束作为基准情景B碳价50元/吨考察低碳价影响情景C碳价150元/吨考察高碳价影响情景D配额制配额量按各微网历史排放的80%分配富余配额可出售四个情景跑下来结果解读重点放在两个层面。第一个层面是碳排放下降幅度直观展示碳价机制或配额机制对系统低碳运行的促进作用。第二个层面更有意思是电能交互结构的变化。碳价升高会改变微网对“本地发电”、“向配网购电”和“与邻居微网交互”三条路径的权衡。由于微网间交互绕开了上级电网规避了购电对应的间接碳排放在高碳价环境下交互电量会明显上升。如果结果图里能清晰呈现这个现象这篇文章的核心贡献就立住了。后续想继续扩展可以把单层ADMM升级为考虑网络潮流约束的两层模型或者把日内反馈层改成模型预测控制的滚动优化框架形成日前计划加日内调整的多时间尺度结构。代码按前面说的分层方式组织后续扩展不用推翻重来只要在对应函数里增加约束和数据即可。最后说一个实操层面的小经验。这个项目最耗时的地方其实不是算法推导而是把Matlab里的变量索引和数据维度理顺。储能SOC约束这类带时间递推关系的约束特别容易出现错位。建议所有时序约束写成一个统一的索引函数不要直接在约束矩阵里裸写数字索引后面调试会省下大量时间。代码能跑通出图之前先确认交互功率曲线表达清楚了“收敛”这件事再去做碳排放和政策情景分析。分布式优化收敛是根其他都是锦上添花。
返回列表