ADMM求解多微网电能交互:计及碳排放的分布式优化Matlab实战
做多微电网调度的朋友应该都有这种感觉模型建起来不难难的是“去中心化”。尤其当每个微网都有自己的运行目标、隐私诉求和碳排放约束时集中式优化一揽子求解的路子就走不通了。这个项目标题——“计及碳排放的基于交替方向乘子法ADMM的多微网电能交互分布式运行策略研究”——本质上就是在解决两件事第一多个微电网之间怎么互相买卖电、怎么协调交互功率第二在考虑碳排放成本的前提下如何用分布式算法求出各微网最优运行方案。我最初拿到这个题目的时候第一反应是“这不就是经典经济调度吗”但真正动手把碳排放约束、交互功率耦合约束和ADMM迭代框架都落地到Matlab里之后才发现里面的细节远比想象中多。这篇文章就从一个动手实现者的角度把这个项目的模型构建、算法设计、代码实现和踩坑过程完完整整地梳理一遍适合正在做多微电网分布式优化、想用ADMM做电能交互但没有现成参考实现的同学。1. 项目整体设计与思路拆解1.1 核心需求与要解决的问题多微电网系统可以理解为一群“各过各的日子、又需要互相帮衬”的独立社区。每个微网内部有自己的光伏、风电、储能和负荷优先自己平衡但遇到光伏大发而本地消纳不完、或者晚间负荷高峰本地发电不够的情况就希望能通过联络线和隔壁微网进行电能交互。这里有个直觉上的冲突每个微网都想从交互中获益——卖电方希望电价高一点买电方希望电价低一点——但交互功率必须满足“隔壁送过来的电等于这边收到的电”这一物理约束。再加上碳排放的约束问题就变成了在满足各微网内部供需平衡、设备出力上下限、储能充放电约束以及微网间交互功率一致性的前提下最小化整个系统的运行成本与碳排放成本之和。解决这个问题的天然思路是集中式优化把全部微网的变量丢给一个中心节点统一求解一个大规模优化问题。但现实中这一思路有两个硬伤。其一是隐私和自治性。每个微网内部的负荷数据、储能配置、机组出力成本曲线都是自己的核心信息没有哪个运营商愿意把底牌全交给一个中心调度机构。尤其是涉及碳排放配额和碳交易成本时每个微网都有自己的碳账本这些数据更敏感。其二是计算复杂性和扩展性。微网数量一多集中式问题的变量数和约束数会爆炸式增长求解时间不可控而且一旦中心节点故障整个系统直接瘫痪。ADMMAlternating Direction Method of Multipliers交替方向乘子法正好是解决这类问题的利器。它的核心思想是“分解-协调”把全局耦合问题拆成每个微网独立求解的本地子问题再通过一个轻量的协调机制——拉格朗日乘子更新——让各微网的解逐步趋向一致。每个微网只需要和邻居交换交互功率的期望值和自己当前的求解结果不需要暴露内部模型。1.2 为什么选择ADMM而不是其他分布式方法分布式优化的方法不止ADMM一种我在定方案之初对比过几类主流方法这里说说我最终选择ADMM的考虑。第一类是对偶分解法Dual Decomposition。思路很直接把耦合约束松弛进目标函数通过更新对偶变量迭代求解。但它的收敛性对目标函数的强凸性要求很高而多微网调度问题里储能SOC约束、机组爬坡约束往往导致目标函数并非严格凸实际跑起来经常出现震荡不收敛的情况。第二类是原对偶分解Primal-Dual Decomposition本质上需要引入额外的一致性协调机制通信拓扑受限而且在处理等式耦合约束时迭代步长非常难调。第三类是增广拉格朗日法Augmented Lagrangian Method虽然加了二次罚项后稳定性好很多但它属于“同时更新所有变量”的批处理方法没有利用问题的可分解结构计算规模仍然很大。ADMM可以看作对偶分解和增广拉格朗日法的结合体它保留了增广拉格朗日法中二次罚项带来的数值稳定性同时通过“交替更新”的方式——先更新原变量再更新对偶变量——把大问题自然拆成了多个本地子问题。每个微网的子问题规模只取决于自身设备数量和整个系统的微网总数无关这个特性让ADMM在电网分布式调度领域几乎是统治级的存在。1.3 碳排放约束如何融入运行策略“计及碳排放”听起来像是个加分项但实际上是这个项目建模时的核心难点之一。碳排放不能简单当成一个固定的惩罚系数加在目标函数里那样做虽然简单但没法真实反映碳交易市场的运作机制研究价值会大打折扣。我的做法是引入阶梯式碳交易机制。具体来说每个微网根据自身的发电结构会获得一个初始碳排放配额。如果实际碳排放低于配额可以把多余的碳配额拿到市场上出售获得收益如果超出配额则必须购买碳排放权而且超排量越大碳价越高——这就是“阶梯”的含义。这个机制会让碳排放成本在目标函数里变成一个分段线性函数虽然增加了模型非线性但更贴近实际碳交易市场的运行逻辑也让分布式算法的收敛性更有看点。这样一来每个微网的本地目标就不只是“让自己运行成本最低”而是“运行成本碳交易成本”的综合最小化而碳交易成本取决于该微网自身的发电出力和碳排放水平。从ADMM的角度来看这其实是个好消息碳排放项是每个微网内部的局部量不涉及微网间的耦合可以天然地落在各自的子问题里不需要额外的分布式处理。2. 模型构建与数学公式拆解2.1 微电网内部结构建模每个微网的内部结构我在建模时采用了最典型也最通用的“源-荷-储”架构包含光伏PV和风电WT两类可再生能源、一个储能系统ESS、本地基础负荷以及与主网和其他微网之间的交互联络线。可再生能源的出力在调度周期内给定为预测值。这里有一个处理细节光伏和风电的出力属于不可调度资源在优化模型中作为已知参数处理不起决策变量。很多人第一次做的时候会想着把可再生能源出力也当成变量去优化这是不对的——不可控资源的出力由天气决定优化模型只能做“消纳”和“弃用”的权衡。储能系统是关键决策变量每个时段有两个状态充电功率和放电功率且同一时段不能同时充放电。为了方便建模我通常引入一个二进制变量来约束充放电互斥关系这样模型就变成了混合整数规划MIP。不过为了能用ADMM高效求解我后来在代码里采用了另一种处理方式把充电功率和放电功率都定义为非负变量通过约束“两者乘积为0”之外的近似方式比如在目标函数中加微小惩罚项来近似互斥效果避免引入整数变量。这个处理思路在工程上很常见只要惩罚系数足够小几乎不影响最终结果但能大幅提升求解速度。微网与主网之间的交互功率同样作为决策变量购电为正、售电为负购电价格和售电价格分别设定售电价格一般低于购电价格这个价差可以模拟电网的网损和利润空间。2.2 目标函数与碳排放成本数学表达系统整体目标是最小化所有微网的总成本这里我把目标函数拆成三个部分运行成本、碳交易成本、微网间电能交互成本。运行成本主要指储能充放电的折旧成本和从主网购电的费用。储能折旧成本可以用充电/放电功率的线性函数近似也可以做成二次函数购电费用就是购电功率乘以分时电价。碳交易成本是最有意思的部分。每个微网在时段t的碳排放量来自两部分向主网购电对应的间接碳排放以及自身可控机组如果有微型燃气轮机等发电设备的话的直接碳排放。在纯新能源微网场景下主要碳排放来源其实是向主网购电因为主网的电力结构中很大比例来自化石能源。每个微网按历史排放水平或装机容量分配到一个初始碳配额实际排放与配额的差值决定它是“卖碳”还是“买碳”。如果用阶梯碳价表达碳交易成本与净排放量E_net之间的关系是分段线性的净排放量在允许范围内时碳价为基础价格超出部分累进加价。这种非线性的阶梯函数在Matlab中可以通过引入辅助变量线性化处理也可以在ADMM子问题中直接用二次函数近似逼近——我实际测试下来用强凸二次函数近似替代阶梯函数的收敛性和计算速度会更好代价是碳交易成本曲线稍微平滑了一点但趋势完全一致。微网间电能交互成本这一项需要特别说明。在集中式优化中微网i向微网j售电的价格是给定的所以交互成本是线性的但在分布式框架下交互功率是由各微网通过迭代协商决定的我在建模时把交互成本拆成了两部分一部分是基于固定交易电价的基础费用另一部分是ADMM迭代时产生的协调项也就是后面的拉格朗日乘子项和罚项。后者不在物理模型里而是算法层面的产物。2.3 关键约束条件与耦合变量识别约束条件分两大类本地约束和耦合约束。本地约束包括每个时段的功率平衡约束本地发电储能放电购电微网交互输入负荷储能充电微网交互输出、储能SOC递推约束及其上下限约束、充放电功率上下限约束、与大电网交互功率上下限约束。耦合约束是这个项目模型的核心也是ADMM能发挥作用的前提任意两个微网i和j之间的交互功率在微网i看来是输出P_ij在微网j看来是输入P_ji两个值必须满足P_ij P_ji 0。这个约束把不同微网的决策变量绑定在一起如果不做分布式分解就必须把所有微网的交互功率变量放进同一个优化问题里求解。识别耦合变量是整个ADMM建模中最关键的一步。我的做法是建立一个邻接矩阵结构微网之间的交互功率变量储存在一个统一的交互矩阵中每个微网只维护自己相关的行和列的局部副本。在通信层面每个微网只需要和直接相连的邻居交换预期的交互功率值不需要全局信息。这个设计保证了算法是真正分布式的而不是挂着分布式名义的中心化求解。3. ADMM算法设计从问题分解到迭代实现3.1 标准ADMM迭代原理回顾ADMM解决的是如下形式的优化问题min f(x) g(z) s.t. Ax Bz c其中x和z是两组不同的变量f(x)和g(z)分别是关于这两组变量的目标函数约束条件把它们线性耦合起来。ADMM的迭代分为三步x更新、z更新、对偶变量更新。每一步都在固定其他变量的前提下求解一个子问题。x更新步骤是在给定当前z和拉格朗日乘子λ的情况下最小化f(x)加上一个关于AxBz-c的二次罚项和线性项。由于这一轮z是已知常数这个子问题实际上退化为一个只与x相关的优化问题非常容易求解。z更新类似固定x和λ求解关于z的最小化问题。最后更新拉格朗日乘子λ ← λ ρ(Ax Bz - c)其中ρ是惩罚参数控制着迭代步长和收敛速度。ADMM一个出色的特性在于它不需要f和g是严格凸函数只需要它们是闭且适当的凸函数。这意味着即使目标函数里有分段线性项比如阶梯碳价只要做了合适的凸化处理ADMM依然能保证收敛到全局最优解。对于多微网调度这样的大规模凸优化问题这个特性非常宝贵。3.2 多微网电能交互问题的ADMM映射要把多微网调度问题映射到ADMM的标准形式核心是定义“耦合变量”和“本地副本”。我采用的方案是“全局变量局部副本”结构。以微网i和微网j之间的交互功率P_ij为例微网i维护一个局部变量P_ij^i表示“微网i认为自己输出给微网j的功率”微网j也维护一个局部变量P_ij^j表示“微网j认为自己从微网i接收的功率”。理想情况下这两个变量应该满足P_ij^i P_ij^j 0。为了把问题写成ADMM的标准形式我引入一个辅助全局变量z_ij表示微网i和微网j之间交互功率的目标一致值。然后要求P_ij^i → z_ij且P_ij^j → -z_ij。换句话说各微网在迭代过程中先基于本地目标优化自己的局部交互变量然后与邻居协调把局部变量向邻居之间的共识值靠拢。这样重写之后x更新这一步自然落到每个微网的本地优化问题中固定z和λ每个微网独立求解自己的最小化问题得出最优的本地出力、储能充放电和交互功率。z更新这一步则是纯代数运算对每一对邻居微网全局变量z_ij (P_ij^i - P_ij^j)/2即两个局部变量的平均值带符号。拉格朗日乘子λ的更新同样很简单λ_ij ← λ_ij ρ(P_ij^i - z_ij)。整个过程中每个微网的内部模型完全不需要暴露给其他微网交互的信息只有P_ij和λ_ij隐私性和通信成本都得到了很好的控制。3.3 收敛判据与迭代停止条件ADMM的收敛判据通常使用原始残差和对偶残差两个指标。原始残差r P_ij^i P_ij^j物理含义就是“不同微网对同一交互功率的认知偏差”对偶残差s ρ(z_ij_new - z_ij_old)物理含义是“全局变量在迭代中的变化幅度”。我在代码里设置了两个停止条件当原始残差和对偶残差都小于容差比如1e-4或者迭代次数达到上限比如500次时停止迭代。实际调试中发现原始残差通常在迭代早期快速下降而对偶残差在接近最优解时可能出现小幅振荡。两种残差同时满足容差条件其实是一个相当严格的判据能保证解的质量但也意味着迭代次数可能会比较多。如果追求速度可以适当放大容差比如1e-3结果差别不会特别明显。3.4 惩罚参数ρ的选取策略与实际影响惩罚参数ρ是ADMM中最重要的超参数它直接影响收敛速度和收敛质量。ρ太小对偶更新步长过小需要很多轮迭代才能把交互功率误差压下去ρ太大虽然原始残差下降快但可能导致对偶变量震荡甚至不收敛。我在项目中采用的是“变惩罚参数”策略每若干轮迭代动态调整ρ。具体规则是如果原始残差与对偶残差的比值过大比如原始残差大于10倍对偶残差就增大ρ反之如果对偶残差大于10倍原始残差就减小ρ。这个策略源自Boyd的经典论文实际操作效果非常好——既避免了固定ρ可能导致的收敛过慢问题也避免了振荡。固定ρ时我建议从1.0开始试这个值在大多数电力系统调度问题中表现稳定。如果发现迭代次数过多再按前面说的动态调整策略做。4. Matlab代码实现与核心环节展示4.1 代码整体框架与功能模块划分整个代码实现我分为五个模块参数初始化模块、数据生成模块、ADMM主循环模块、子问题求解模块、结果可视化模块。参数初始化模块负责配置微网数量、调度时段数、设备容量、电价曲线、碳排放参数、ADMM参数等基础数据。为了让代码具备通用性我把所有参数集中放在脚本开头的参数区方便直接修改后适配不同场景。数据生成模块负责生成光伏出力、负荷曲线等输入数据。由于没有现成的实测数据我采用典型日曲线加随机扰动的生成方式选择24小时调度周期、1小时一个时段模拟一整天的运行情况。每个微网的光伏出力和负荷曲线都设定了不同的峰谷特性这样能让电能交互真正“有生意可做”——比如微网A是工商业负荷为主白天负荷高但光伏不足微网B是居民区为主白天光伏富裕晚上负荷走高。这种差异化设置才能体现多微网交互的价值。ADMM主循环模块是整个代码的核心负责协调各微网的迭代求解过程。子问题求解模块是每个微网在自己的“沙盒”里独立求解本地优化问题。结果可视化模块则负责把各微网的运行曲线、交互功率、碳排放情况画出来。4.2 子问题求解基于二次规划的本地优化实现每个微网的本地子问题本质上是一个带约束的二次规划QP问题。我用Matlab的quadprog函数求解因为Matlab自带优化工具箱不需要额外安装第三方求解器对于验证算法和研究性质来说完全够用。子问题求解的核心结构如下面的伪代码所示其中H和f是目标函数的二次项和一次项系数矩阵Aeq和beq是等式约束A和b是不等式约束lb和ub是变量上下限。% 微网i的本地子问题求解 % 变量定义x [P_ch; P_dis; P_buy; P_sell; P_ex; SOC] H_i 2 * rho * (L_i * L_i) H_base; f_i f_base rho * (-z_i - lambda_i / rho) * L_i; % 等式约束功率平衡、SOC递推 Aeq_i [...]; beq_i [...]; % 不等式约束充放电上下限、交互功率上下限 A_i [...]; b_i [...]; % 边界约束 lb_i [...]; ub_i [...]; [x_opt, fval] quadprog(H_i, f_i, A_i, b_i, Aeq_i, beq_i, lb_i, ub_i, [], options);需要特别注意的是在ADMM框架中目标函数中的二次罚项会改变Hessian矩阵的结构。由于我引入的是“局部副本向全局变量收敛”的约束罚项实际上是关于(P_ij - z_ij)的二次项展开后会贡献到H矩阵和f向量中。这也是为什么本地子问题仍然是二次规划而不是线性规划——如果没有罚项目标函数是线性的用linprog就能解决加了罚项后就必须用quadprog。4.3 全局协调步骤的关键代码实现全局协调步骤是ADMM区别于其他分解方法的关键所在。这一步在中心协调器中完成实际运行中可能由任意一个微网或者一个轻量级通信节点负责主要做三件事更新全局变量z、更新拉格朗日乘子lambda、计算残差判断收敛。% 更新全局变量对每一对交互的微网z取两个局部变量的均值 for k 1:size(interaction_pairs, 1) i interaction_pairs(k, 1); j interaction_pairs(k, 2); z(i,j,:) (P_ex_local(i,j,:) - P_ex_local(j,i,:)) / 2; z(j,i,:) -z(i,j,:); end % 更新拉格朗日乘子 lambda lambda rho * (P_ex_local - z); % 计算原始残差和对偶残差 r_prim norm(P_ex_local(:) - z(:)); s_dual rho * norm(z(:) - z_old(:));这里用了一个trick交互功率矩阵是反对称的P_ex_local(i,j)表示微网i输出到微网j的功率P_ex_local(j,i)表示微网j输出到微网i的功率。在迭代过程中这两个值由各自的微网求解得出并不一定满足反对称关系。全局协调器把它们平均后赋值给z然后把z分发回各微网作为下一步迭代的目标。这个“平均”操作看起来简单但正是ADMM能收敛的核心机制——它保证所有微网最终对同一交互功率达成一致。4.4 微网间交互功率与碳排放结果的典型输出以两个微网为例我设置微网A白天光伏发电量大、负荷较低微网B白天负荷高、光伏不足。运行ADMM后得到的结果很符合物理直觉白天时段微网A把多余的电卖给微网B晚上时段微网B储能放完、负荷下降不再需要购电。从输出结果看两个微网之间的交互功率曲线呈“白天为正、夜间近乎为零”的形态这正是电能交互的典型特征。碳排放方面由于白天微网A向B输送了清洁光伏电力微网B的购电成本降低同时整体碳排放也明显下降——因为微网B不需要从主网购买那么多含碳量高的电了。这个结果说明电能交互不仅带来了经济收益还带来了环境收益。我一开始跑代码的时候发现一个很有意思的现象如果不加碳排放约束两个微网的交互功率会比加约束后大得多。原因是碳交易成本相当于给“从主网购电”这一行为加了一笔隐性税让微网更倾向于和邻居做交易来降低自己的购电量。这说明“计及碳排放”这个约束确实会改变微网的调度行为和交互策略而不只是一个锦上添花的统计指标。5. 常见问题与排查技巧实录5.1 ADMM震荡不收敛的排查经验这是我在整个项目里花时间最多的一个坑。ADMM不收敛通常表现为残差曲线来回震荡、迭代次数打满但结果还在漂移。排查时我建议按以下顺序逐一排除。第一步检查模型是不是凸的。ADMM要求目标函数是凸函数。如果约束里包含了非凸项比如储能充放电互斥的二进制变量或者在目标函数里用了非凸的表达都会导致不收敛。我最初用二进制变量做充放电互斥时几次出现迭代到中间阶段残差开始震荡换掉二进制变量后就稳定了。第二步检查惩罚参数ρ是否合适。ρ过大或过小都可能导致收敛问题。如果残差下降速度极慢通常是ρ太小如果残差初期下降很快但后期剧烈震荡通常是ρ太大。我在调试时会在日志里打印每个时段的交互功率值能直观看出振荡幅度和频率比只看残差数字要直观得多。第三步检查q尺度一致性。不同变量的数量级差异过大会让残差计算失衡比如储能容量是MWh级别功率是MW级别两者相差一个量级。此时应该在模型中做归一化处理或者把ρ按变量分组设置不同的值。我建议把功率统一折算到某个基准值比如1MW这样各变量的数量级一致收敛会顺畅很多。5.2 动态调整惩罚参数ρ的调试细节动态调整ρ可以让算法在不同阶段都保持良好的收敛速度。我在调试代码时遵循的标准框架是if norm_r 10 * norm_s rho rho * 2; elseif norm_s 10 * norm_r rho rho / 2; else rho rho; % 保持当前值 end但这里有一个容易忽略的细节ρ改变后拉格朗日乘子λ也需要做相应的缩放。具体做法是在改变ρ之前把λ同时除以新的ρ值否则对偶变量会突然“跳变”导致后续迭代不稳定。这个缩放操作是ADMM实现中最容易遗漏的细节我最初因为忘了做λ缩放出现了一改ρ就发散的问题排查了很久才找到原因。另外一个实用建议是不要频繁调整ρ建议每隔20到50轮迭代检查一次残差比值再决定是否调整。这个项目在10个微网规模下测试动态ρ策略通常可以把迭代次数降低30%到40%效果非常明显。5.3 quadprog求解子问题时常见的数值问题用quadprog求解本地子问题时最常见的报错是“Hessian矩阵不是正定矩阵”。这在ADMM迭代中很常见因为罚项虽然会贡献二次项但如果罚项矩阵L_i*L_i是半正定的加上H_base后仍然是半正定而不是严格正定quadprog就可能报错或者求解缓慢。我的解决办法是给Hessian矩阵加一个很小的单位阵倍数比如加上1e-8 * eye(n)。这个正则化操作在数值上几乎不影响最优解但能让quadprog稳定求解。另一个常见问题是变量初始值设置不合理导致quadprog在第一个迭代轮次就报不可行。建议初始化时把所有功率变量设为零或者接近零的合理值拉格朗日乘子设为零这样第一次子问题求解就有了一个明确可行的起点。还有一个我踩过几次的坑quadprog的边界约束lb和ub如果设置得过于严格会在某些极端场景下导致不可行。比如光伏大发加上负荷很低的时刻储能已经充满、交互功率也到达上限此时功率平衡约束可能无法满足。解决办法是在约束中增加弃光变量——允许微网在极端情况下舍弃部分光伏出力这个变量在实际调度中也存在并不是数学上的“作弊”。5.4 计算时间与扩展性表现在10个微网、24个时段的算例规模下我用Matlab R2022b在普通台式机上运行ADMM迭代约120轮收敛到1e-4容差总耗时约40秒。其中每个微网每次迭代的本地QP求解耗时约0.02秒主要时间花在Matlab的函数调用开销上。如果追求更快的求解速度可以把子问题从quadprog换成yalmip或gurobi求解器或者写一个定制的内点法求解器速度提升会非常明显。从算法可扩展性来看ADMM最大的优势在于计算复杂度几乎不随微网数量线性增长。因为每轮迭代中每个微网的子问题都是独立求解的理论上可以并行计算。虽然是单机运行但代码结构已经支持了并行计算——只要把循环改成parfor就能自动利用多核CPU并行处理各微网的子问题。我在8核机器上测试过并行化后10个微网的算例耗时可以降到15秒以内提速接近三倍。如果部署到真实的多微网系统中各微网天然分布在不同的地理位置通信和计算都是并行的ADMM的这种可扩展性优势会更加突出。5.5 问题排查速查表现象可能原因排查与解决方案残差震荡不收敛目标函数非凸、ρ设置不当检查是否有整数变量或非凸项替换为凸近似调整ρ或启用动态ρ策略迭代次数过多收敛慢ρ过小、初始值不佳增大ρ给出合理初始解使用动态ρ更新quadprog报Hessian不正定二次项矩阵半正定给H矩阵加1e-8的微小正则化项交互功率长时间不收敛全局变量更新逻辑错误检查反对称赋值是否正确确认z的更新公式子问题不可行约束过紧、极端场景增加弃光/弃风变量放宽边界约束本地结果合理但全局次优罚参数ρ终值过大迭代结束后用无罚项的本地QP做一次修正求解5.6 拓展方向从算例验证向实际应用延伸做完了这个项目后续可以自然延伸的方向有几个。其一是把单目标优化扩展成多目标——比如同时考虑运行成本最小化和碳排放最小化用加权法或帕累托前沿法分析经济性与环保性之间的权衡关系。其二是引入不确定性光伏和负荷的预测误差是实际运行中无法回避的可以结合鲁棒优化或随机规划的思路考察交互策略的鲁棒性。其三是把ADMM与分布式模型预测控制MPC结合起来实现滚动时域的分布式能量管理这在微电网实时调度中有很强的应用价值。我个人在实际操作中的体会是ADMM的数学原理并不复杂真正难的是把实际问题巧妙地映射到ADMM框架里尤其是耦合变量的识别与处理。很多人卡在“模型建好了但不知道哪些变量需要分布式迭代”这一步根源在于没有对耦合约束做系统的梳理。只要你把耦合约束找出来、定义好局部副本和全局变量、再套上ADMM的迭代公式剩余的工作就是调参和Debug了。如果你正在做多微电网或其他分布式优化方向的研究希望这篇文章能帮你少走一些弯路。