ARTICLE DETAIL

资讯详情

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

目标级联法ATC在微网群分布式优化调度中的Matlab实现与调参经验

目标级联法ATC在微网群分布式优化调度中的Matlab实现与调参经验 先说点实际的。微网群调度这事近几年在EI论文里几乎成了标配研究对象但真正能把分布式优化跑通、跑稳、还能讲清楚每一步在干什么的资料其实很少。尤其是目标级联法Analytical Target Cascading, ATC这种从机械设计领域跨界过来的算法很多做电力系统的同学第一次接触时会卡在“为什么这么迭代”“罚参数到底怎么调”“Matlab里怎么落地”这几个问题上。这篇文章就把目标级联法在微网群多主体分布式优化调度中的应用拆开揉碎来讲。我会先用一个具体场景说明为什么集中式优化在微网群里不好使再讲清楚ATC的核心机制和数学原理然后给出一套完整的Matlab实现框架包括参数设置、核心代码思路、迭代流程最后把我在调试过程中踩过的坑和总结的经验一并列出来。内容比较长建议收藏了慢慢看。1. 集中式优化解决不了的问题微网群调度的三个现实痛点1.1 数据隐私与主体利益冲突先描述一个场景。假设你手头有3个相邻的微电网A是工业园区屋顶全是光伏白天发电多到用不完B是居民小区晚上负荷飙升白天相对平稳C是个小型商业综合体配有储能但对电价极其敏感。这三个微网之间通过联络线连在一起形成一个微网群。如果采用传统集中式优化那么一个调度中心需要拿到A、B、C所有发电设备参数、负荷预测曲线、储能SOC状态、微燃机启停成本、各自与配电网的交易电价……一句话所有隐私数据必须全部上交给调度中心。这时候问题就来了A园区的经理未必愿意把自己工厂的生产班次和精确负荷透传出去C商业体的运营方也不想让竞争对手知道自己储能系统的真实成本和充放电策略。这就是微网群调度第一个痛点——多主体之间既想合作共赢又不想交底。目标级联法恰恰就是为解决这类问题设计的。它的核心思路是“上级给目标下级报响应偏差来协调”各微网只需要和上级协调器交换一个联络线功率计划值而不需要披露任何内部隐私数据。每个微网仍然拥有自己的独立优化权只是在外部功率边界下做自优化。1.2 单点故障与通信依赖第二个痛点是可靠性。集中式模式下所有微网把自己算好的运行计划或原始数据汇到调度中心中心算完再把全局最优解下发。假设这个中心宕机、通信链路过载、或者某条数据链路故障整个微网群的优化调度就会停摆。对于一个真实运行的微网群来说这意味着可能从“经济调度模式”直接退化到“各自为战”。分布式优化的价值就在这它没有唯一的核心节点。每个微网都能独立求解自己的局部优化问题上级协调器即使暂时收不到某个微网的反馈其他微网依然可以按上一次迭代的目标值继续运行系统不会立刻崩溃。这在工程上叫“graceful degradation”优雅降级对实际项目来说非常关键。1.3 模型规模与计算复杂度第三个痛点可能更直观——计算量。假设微网群里有20个微网每个微网内部有光伏、风机、储能、柴油发电机、可调负荷、电动汽车充电桩等10余种可调度资源优化周期是24小时、分辨率为1小时。集中式模型光决策变量就会突破5000个如果再考虑整数变量比如机组启停问题规模会进一步爆炸。就算计算能力够强还有一个严峻问题模型一旦变化全盘重算。比如某个微网今天多投运了一台储能集中式模型里这个微网的约束矩阵就变了得重新建模、重新求解。而分布式结构天然支持扩展新增一个微网节点时其他微网和协调器的模型完全不用动。2. 目标级联法的核心机制把大问题拆成可协商的小问题2.1 ATC从哪里来从汽车设计到微网群的跨界目标级联法最早是密歇根大学Kim等人在2000年前后提出的用来解决大型产品设计中的多学科优化问题。最经典的场景是汽车车身设计整车有性能目标底盘、发动机、车身各子系统需要在结构、重量、成本等多个学科目标之间协同但各学科模型属于不同团队、不同仿真工具、不同保密级别。这个逻辑放到微网群里简直天然匹配。整车就好比微网群底盘发动机好比各微网学科间共享参数好比联络线功率。ATC的核心思想也不是什么玄乎的东西它做的就是一个事层与层之间只交换目标值和响应值通过罚函数把上下层目标之间的不一致性逐步压小。2.2 数学原理与迭代公式拆解用数学语言来描述微网群场景下的ATC问题。设微网群协调器MSO设定第i个微网的联络线功率目标为 (t_i)第i个微网在收到目标值后求解自己的优化问题返回实际响应值 (x_i)。理想情况下 (x_i t_i)但这几乎不可能一开始就满足。ATC的做法是把偏差 (x_i - t_i) 作为罚项写进下层微网的目标函数里让微网在优化自身成本的同时不得不兼顾协调器给定的目标。第i个微网的子问题可以写作[ \min_{x_i} ; f_i(x_i) \lambda_i (x_i - t_i) \rho_i |x_i - t_i|^2 ]其中(f_i(x_i)) 是微网i自身的运行成本(\lambda_i) 是拉格朗日乘子记录历史偏差的累积(\rho_i) 是罚参数控制当前偏差的惩罚强度(t_i) 是协调器下发的目标值(x_i) 是微网自优化的结果。请注意(\lambda_i) 和 (\rho_i) 在单次迭代中对下层微网来说是常数所以这个子问题本质上是一个带二次罚项的局部优化问题可以直接调用Matlab的quadprog、fmincon或者YALMIPGurobi来求解。收敛判断和乘子更新遵循以下链路各微网求解完毕返回 (x_i^{(k1)})协调器判断 (\max_i |x_i^{(k1)} - t_i^{(k)}| \varepsilon) 是否成立如果不满足更新乘子和目标值 [ \lambda_i^{(k1)} \lambda_i^{(k)} 2\rho_i (x_i^{(k1)} - t_i^{(k)}) ] [ t_i^{(k1)} x_i^{(k1)} ] 或者做带松弛的更新 (t_i^{(k1)} \alpha x_i^{(k1)} (1-\alpha)t_i^{(k)})其中 (\alpha \in (0,1])返回第1步继续迭代。这个过程可以用一个生活化的类比来理解协调器像一个家里管账的家长月初给每个孩子定零花钱限额 (t_i)孩子们按这个限额报自己的实际开销计划 (x_i)超出部分要解释并接受“惩罚”。家长根据偏差调整下一轮限额几轮之后全家预算就对齐了。2.3 为什么不是ADMMATC的定位差异很多做优化的同学会问同样是分布式优化为什么不用更火的交替方向乘子法ADMM这个问题在微网群里确实值得掰扯一下。ADMM通常要求原问题具备可分的凸结构并且两个子问题之间的耦合约束被写进增广拉格朗日函数中。它的收敛性理论很漂亮但前提条件也苛刻。ATC则不同它最初就是为层级化多学科问题设计的天然契合“协调器-多个子问题”这种结构。在实际微网群场景中各微网的内部约束往往包含0-1变量机组启停、非线性约束潮流方程、非凸约束储能充放电效率这些情况下ATC的经验表现通常更稳健。此外ADMM的交替迭代是“同级协商”两个相邻微网要直接交换边界信息而ATC是“上下级协商”微网之间不需要任何直接通信所有信息交换通过协调器中转。这一点在多主体商业场景中格外友好——两个直接竞争的微网不希望互相知道对方的交易电价但都愿意和公共协调器对接。3. 微网群分布式优化调度的数学建模3.1 微网内部设备模型与约束要让ATC跑起来首先得把一个微网内部的模型建清楚。我以最常见的三类设备为例来搭建一个通用微网模型。光伏与风机这类新能源机组在调度层面通常按预测功率作为负的负荷处理不参与优化决策但需要作为功率平衡项的输入。要注意的是如果微网内新能源渗透率较高调度模型里最好预留一个弃光/弃风变量否则求解器可能因为功率过剩无解。储能系统的模型相对复杂一些[ SOC_{t1} SOC_t \frac{\eta_{ch} P_{ch,t} \Delta t}{E_{cap}} - \frac{P_{dis,t} \Delta t}{\eta_{dis} E_{cap}} ]约束包括SOC上下限(SOC_{min} \le SOC_t \le SOC_{max})充放电功率上限(0 \le P_{ch,t} \le P_{ch,max})、(0 \le P_{dis,t} \le P_{dis,max})充放电不能同时进行(P_{ch,t} \cdot P_{dis,t} 0)实际建模时用大M法或二进制变量处理调度周期结束SOC约束(SOC_{T} \ge SOC_{init})保证长期可持续运行微型燃气轮机的模型是最典型的可控机组。运行成本通常用二次函数近似[ C_{MT,t} a P_{MT,t}^2 b P_{MT,t} c ]出力上下限、爬坡约束、最小启停时间约束都要考虑。如果做简化版本可以先把启停变量去掉只保留连续出力变量和爬坡约束这样问题就是个二次规划QP求解速度极快适合先跑通ATC框架。3.2 微网群耦合约束与交易机制微网群层面的核心耦合量是联络线功率。第i个微网与微网群其他微网的实际交换功率 (P_{ex,i,t})也就是ATC里的响应变量 (x_i)协调器下发的目标值 (t_i) 是根据全局供需关系给出的推荐交换功率。这里有一点需要区分如果微网群内采用的是合作调度模式也就是所有权归同一个运营主体那么耦合约束就是简单的功率平衡[ \sum_{i1}^{N} P_{ex,i,t} 0 ]如果微网群采用市场化交易模式则每个微网可能与指定的邻居有独立联络线耦合约束变成两两之间的交易功率约束。前者建模更简单后者更贴近多主体博弈场景。使用ATC时两种模式都能处理区别只在于协调器的约束形式。3.3 目标函数设计成本、碳排放与自治偏好第i个微网的目标函数可以设计为[ \min \sum_{t1}^{T} \left[ C_{MT,i,t} C_{buy,i,t} - R_{sell,i,t} C_{SOC,i,t} \lambda_{i,t}(P_{ex,i,t} - t_{i,t}) \rho_{i,t}|P_{ex,i,t} - t_{i,t}|^2 \right] ]其中(C_{buy,i,t}) 是从配网购电的成本(R_{sell,i,t}) 是向配电网售电的收益(C_{SOC,i,t}) 可加一个SOC越限惩罚项尽量让储能不过充过放。如果想兼顾碳排放可以给微燃机发电成本加一个碳价系数这样减排目标就通过价格信号内化到每个微网的局部决策里了很适合当前双碳政策背景下写项目申报书或者发论文的场景。4. Matlab代码实现从架构到逐模块复现4.1 整体程序框架与数据流一套可跑的ATC微网群调度代码我建议分成以下几个文件文件功能main_atc.m主脚本负责初始化、循环迭代、收敛判断、结果汇总case_3mg.m参数定义文件3个微网的设备参数、负荷曲线、新能源预测功率mso_update.m协调器上层逻辑更新拉格朗日乘子、罚参数、目标值mg_optimize.m单个微网的优化求解函数输入目标值输出响应值和成本plot_results.m结果可视化画功率平衡、SOC曲线、迭代收敛曲线数据流的主循环如下初始化 λ, ρ, t for k 1 : k_max for i 1 : N [x_i, obj_i] mg_optimize(..., t_i, λ_i, ρ_i) end max_dev max(abs(x - t)) if max_dev ε break end [λ, t, ρ] mso_update(x, t, λ, ρ) end4.2 核心代码ATC迭代主循环这一段是整个程序的主心骨代码不复杂但细节容易出错。%% main_atc.m %% 初始化 N 3; % 微网数量 T 24; % 优化时段 rho 10 * ones(N, 1); % 初始罚参数 lambda zeros(T, N); % 拉格朗日乘子 t zeros(T, N); % 协调器下发的目标值初始全部为0 x zeros(T, N); % 各微网返回的响应值 alpha 0.8; % 目标值更新松弛因子 eps 1e-3; % 收敛阈值 k_max 100; % 最大迭代次数 for k 1 : k_max % 下层各微网独立求解 for i 1 : N [x(:, i), obj(i, k)] mg_optimize(i, t(:, i), lambda(:, i), rho(i)); end % 收敛判断 max_dev max(max(abs(x - t))); dev_history(k) max_dev; if max_dev eps fprintf(ATC收敛于第%d次迭代\n, k); break; end % 上层协调器更新乘子和目标值 lambda lambda 2 * rho .* (x - t); % 注意逐项更新 t_new alpha * x (1 - alpha) * t; t t_new; end这里有一个调试中很值得注意的细节目标值的更新公式是否需要加松弛因子。最初我写过不加松弛的版本也就是直接把 (t^{(k1)} x^{(k)})结果在某些参数组合下出现了振荡。后来翻了Kim的原始论文发现对于非凸子问题带松弛的更新确实能显著改善收敛稳定性。建议你们从 (\alpha0.8) 开始调。4.3 微网优化函数mg_optimize的实现这是每个微网内部求解的核心函数。我用YALMIP建模因为它语法简洁特别适合教学和快速修改模型。以下是一个带储能、微燃机、可交易功率的微网子问题示例function [x_out, obj_val] mg_optimize(i, t, lambda, rho) %% 载入微网i的参数 mpc load_mg_params(i); % 自定义函数读取该微网的基础数据 %% 定义决策变量 Pmt sdpvar(1, T); % 微燃机出力 Pbuy sdpvar(1, T); % 向配网购电 Psell sdpvar(1, T); % 向配网售电 Pch sdpvar(1, T); % 储能充电功率 Pdis sdpvar(1, T); % 储能放电功率 SOC sdpvar(1, T1); % SOC轨迹 Pex sdpvar(1, T); % 联络线交换功率与微网群 % 注意Pex为正值表示向外送电负值表示从外购电 %% 约束条件 Constraints []; % 功率平衡 for t 1 : T Constraints [Constraints, ... Pmt(t) Pbuy(t) Pdis(t) mpc.Ppv(t) ... mpc.Pload(t) Pch(t) Psell(t) Pex(t)]; end % 微燃机出力范围 Constraints [Constraints, ... mpc.Pmt_min Pmt mpc.Pmt_max]; % 储能约束 Constraints [Constraints, ... 0 Pch mpc.Pch_max, ... 0 Pdis mpc.Pdis_max, ... mpc.SOC_min SOC mpc.SOC_max, ... SOC(1) mpc.SOC_init, ... SOC(T1) mpc.SOC_init]; for t 1 : T Constraints [Constraints, ... SOC(t1) SOC(t) (mpc.eta_ch * Pch(t) - Pdis(t) / mpc.eta_dis) / mpc.Ecap]; end % 联络线功率限值 Constraints [Constraints, ... -mpc.Pex_max Pex mpc.Pex_max]; %% 目标函数 Objective 0; for t 1 : T % 微燃机成本二次函数线性化或用quad形式 Objective Objective ... mpc.a * Pmt(t)^2 mpc.b * Pmt(t) mpc.c; % 购售电成本/收益 Objective Objective ... mpc.price_buy(t) * Pbuy(t) - mpc.price_sell(t) * Psell(t); % ATC罚函数项 Objective Objective ... lambda(t) * (Pex(t) - t(t)) rho * (Pex(t) - t(t))^2; end %% 定义并求解 ops sdpsettings(solver, quadprog, verbose, 0); optimize(Constraints, Objective, ops); x_out value(Pex); obj_val value(Objective); end这里有几个建模细节要特别注意第一(Pex) 的正方向必须全系统统一。我见过很多初学者在2个微网的程序里定义方向不一致导致迭代永远不收敛。建议在参数文件里就写清楚“正方向为微网向公共母线送电”所有微网都遵守这个约定。第二储能SOC的整数约束处理。上面代码用连续变量建模隐含假设了充放电效率恒定且非同时充放电约束被忽略。如果有两套独立决策变量Pch和Pdis会出现同时充电又放电的荒谬局面。更严谨的做法是引入二进制变量或使用互补约束但前者会让问题变成MIQP、大幅拖慢迭代速度。在跑通框架阶段可以先加一个大M约束 (Pch Pdis \le P_{max,limit}) 来近似。第三目标函数里 (\rho (Pex - t)^2) 展开后会出现 (-2\rho Pex \cdot t \rho Pex^2 \rho t^2)其中 (\rho t^2) 是常数项。建议在Matlab代码里先展开表达式再传给求解器或者干脆让YALMIP自己处理但要知道这个项对求解器没有影响出现“Constant”警告时不用慌。4.4 协调器更新函数与初值选择协调器的职责就是更新乘子、罚参数和目标值。下面是核心逻辑function [lambda_out, t_out, rho_out] mso_update(x, t, lambda, rho, alpha, beta) %% x: T×N矩阵各微网返回的联络线功率 %% t: T×N矩阵当前目标值 %% alpha: 目标值更新松弛因子一般0.6~0.9 %% beta: 罚参数放大因子一般1.0~1.1不宜过大 lambda_out lambda 2 * rho .* (x - t); t_out alpha * x (1 - alpha) * t; rho_out beta * rho; end关于初值选择我的建议是所有微网的初始 (t) 设为0也就是先让各微网在无联络线交互的状态下自优化拉格朗日乘子 (\lambda) 也初始化为0罚参数 (\rho) 的初值不要太大也不要太小通常取10~100之间。太小的话需要迭代很多轮才能把偏差压下去太大则会让子问题目标函数里的罚项喧宾夺主扭曲了原本的最小化运行成本目标。5. 算例实测收敛轨迹、迭代次数与调度结果分析5.1 算例设置3个微网、24小时调度为了让代码跑起来且结果有意义我构造了一个具体的算例。三个微网的基本参数如下表所示微网新能源配置可控设备峰值负荷备注MG1光伏500 kW储能300 kW/600 kWh350 kW白天高发低用MG2风电300 kW微燃机200 kW300 kW晚间负荷较高MG3光伏200 kW储能200 kW/400 kWh250 kW日间商业负荷为主购售电价采用峰谷分时电价峰时段10:00-15:00、18:00-21:00购电0.98元/kWh、售电0.75元/kWh谷时段23:00-7:00购电0.32元/kWh、售电0.25元/kWh平时段介于两者之间。微燃机成本函数取 (0.03P^2 12P 20)。收敛阈值设定为1e-3 kW最大迭代次数100次。用我上面给的参数跑下来大约第23次迭代满足收敛条件。5.2 收敛轨迹的三个关键观察观察收敛曲线时主要看三个指标的变化轨迹联络线功率偏差 (\max|x-t|)、各微网目标函数值、以及总系统成本。第一个观察偏差曲线呈锯齿状下降前期快、后期慢。前5次迭代偏差从几百万kW级别迅速降到几百kW但从第10次开始下降速度明显放缓主要原因是罚参数 (\rho) 增长过慢。如果发现后期收敛太慢可以把 (\beta) 从1.0改到1.05能明显加速。但 (\beta) 不能太大否则会出现后期振荡不收敛的怪现象。第二个观察各微网的目标函数值在迭代过程中先上升后下降。原因是初始时联络线功率目标为0微网各自按孤岛状态优化成本最低加入ATC罚项后微网被迫调整自己的交换功率计划产生了额外的调整成本所以目标值上升。随着迭代进行协调器给出了更合理的全球目标微网在自身成本和联络线约束之间找到平衡点目标值回落到一个稳定区间。第三个观察系统总成本比完全孤岛状态下降约8%。这个数字来自我的算例你们用不同数据会有差异但趋势是一致的微网群通过功率互助减少了向配电网的高价购电同时把新能源富余电量在群内消化避免低价上网。5.3 与集中式优化结果对比我把ATC分布式优化的结果和同样的模型用集中式求解全局优化器直接解做了对比。两个值得记录的数据成本偏差分布式优化的总成本比集中式最优解高约1.2%。这个偏差主要来源于罚函数迭代只能逼近全局最优而不能精确达到。如果想减小这个偏差可以调小收敛阈值到1e-4但迭代次数会显著增加通常要50次以上。单次迭代耗时在数据规模为3微网×24时段电机下每个微网子问题求解不到0.1秒单次迭代串行求解3个子问题约0.3秒整个ATC流程约7秒。集中式求解包括建模和全局优化约0.5秒。看起来集中式更快但请注意实际微网群场景中子问题是可以并行计算的而且集中式需要大量的数据传输和统一建模时间这部分的成本被“算得快”掩盖了。5.4 调度结果可视化的几个实用图跑完代码后我建议至少画四张图各微网联络线功率时间序列看出谁在哪个时段送电、受电三个微网的功率平衡堆叠图看出光伏、储能、购电、负荷的构成储能SOC轨迹检查有没有越限或末段SOC不满足约束收敛曲线横轴迭代次数纵轴对数坐标偏差。画图时注意一个排版细节如果用subplot画多个子图记得把X轴时间坐标统一否则对比起来特别费劲。我通常把XTick设为0:6:24再手动标上“0h, 6h, 12h, 18h, 24h”看起来专业很多。6. 跑通代码后必须知道的调试技巧与坑6.1 罚参数初值的选择一个靠经验但可量化的判断罚参数 (\rho) 的初值直接影响收敛速度和一个更隐蔽的问题——解的合理性。如果 (\rho) 初始值太大比如10000看起来罚项很强但子问题目标函数被罚项主导微网几乎完全跟随协调器目标失去了“自身经济性优先”的意义最终全局成本可能很差。如果 (\rho) 初始值太小比如0.01那么前几轮迭代里微网根本不理会协调器给的目标偏差巨大收敛极慢。我的经验做法是先算一个基准。用完全孤岛模式去掉联络线变量求一次各微网的最优成本再乘以一个系数作为罚项的量级参考。比如MG1孤岛成本约3500元/天联络线功率偏差希望控制在50 kW量级那 (\rho) 取 (0.1 \times 3500 / 50^2 \approx 0.14) 显然太小取 (3500 / 50^2 \approx 1.4) 更合理。实际我会直接取10~50之间的值然后以2倍为单位逐步放大观察收敛曲线形态来调。6.2 乘子更新公式踩过的坑方向与维度在写mso_update函数时很容易在维度上翻车。(\lambda) 在代码里是T×N矩阵而 (\rho) 是N×1向量。做lambda 2 * rho .* (x - t)时Matlab的隐式扩展虽然能跑但逻辑上很容易错位。我的习惯是先把所有量都展开成T×N矩阵再运算增加一行rho_full repmat(rho(:), T, 1);这样每一步调试都能用size()核查避免维度不匹配导致的莫名奇妙的NaN。另外一个屡见不鲜的坑是“越迭代越发散”。如果遇到这种情况先检查有没有把前后迭代的变量混用。x必须是当前迭代求解出的新值t迭代更新也必须严格用当前值。新手容易犯的错误是目标值更新用了上上轮的旧t导致乘子更新和目标值更新不在同一时间步上整个迭代必然发散。6.3 求解器的选择YALMIPGurobi还是fmincon在子问题求解器层面不同选择的差异比我预想的要大得多。如果模型是连续二次规划QP如储能连续模型微燃机二次成本线性ATC罚项那么quadprog或Gurobi都是很好的选择。Gurobi在学术界免费求解速度快鲁棒性极强是我最推荐的路子。如果模型引入了0-1变量如储能非同时充放电、机组启停状态问题变成MIQP。这种情况下fmincon等基于梯度的求解器无能为力Gurobi仍能出色地解决中小规模问题。我实测过3微网×24时段的MIQPGurobi单子问题求解时间从0.1秒涨到1秒左右对整个ATC迭代流程而言完全可以接受。至于YALMIP它更像一个建模语言而不是求解器。它的价值在于让你快速构建和修改模型写起来比裸调用optimproblem快很多。但YALMIP也会有让人抓狂的时候——比如自动变量展开导致内存爆炸、非线性约束被错误识别等。因此我建议最终要反复调参和跑多次实验时可以先在YALMIP里把模型调通然后考虑改写成optimproblem结构以提升运行效率。6.4 常见报错与排查思路我整理了几个高频问题及其排查方向现象可能原因排查建议迭代发散偏差越来越大罚参数更新过快beta1.2或目标值未做松弛先固定rho不更新只更新lambdaalpha降到0.5结果长期不收敛但偏差很小收敛阈值小于求解器数值精度阈值不要低于1e-4检查是否有量级相差悬殊的变量子问题无解/不可行功率平衡约束与联络线限值冲突储能初末SOC约束太苛刻先放开联络线限值检查储能初始SOC是否满足末期SOC要求目标函数出现NaN罚参数过大导致表达式溢出求解器数值问题对rho做限制rho min(rho, 1e4)总成本比孤岛模式还要高收敛阈值太松全局目标还没协调好就停了收紧阈值检查是否给所有微网都加了ATC罚项漏加会导致部分微网“自由放飞”6.5 进阶优化加速收敛的几种工程技巧如果确定要让ATC跑大规模案例比如20个微网、288个时段下面几个技巧能帮上大忙。第一子问题并行化。每个微网子问题是完全独立的理论上是天然并行的。用Matlab的parfor代替for跑子问题循环在6核机器上实测能获得3~4倍加速。唯一要注意的是如果用了parfor每个worker都要能访问到子问题函数和参数文件建议先用addAttachedFiles(gcp, ...)把所有依赖文件打包给worker。第二热启动。第一次迭代时所有变量从0开始优化速度慢。但如果上一轮的求解结果被保存下来作为下一次迭代的初值求解器就能快速收敛。尤其对MIQP问题热启动带来的加速非常明显。代码上可以用optimize(Constraints, Objective, ops, old_result)这种YALMIP指定的初始解格式。第三预热协调器。在最开始的1~3次迭代中可以只让微网优化、不更新乘子先让各微网对“自由交换功率”有个初步感受再进入正式的ATC循环。这种方法叫“零次迭代预热”效果相当于给协调器一个更合理的初始目标值可以显著减少后续迭代次数。最后分享一个我在做这个项目时的体会跑通ATC微网群调度其实不难真正花时间的是理解“协调器-子问题”之间那种微妙的关系。我做第一版代码时花了整整一个周末调不收敛的问题最后发现是我在更新lambda时乘了2而罚参数又乘了beta两个放大因子叠加导致振荡。把迭代过程完整打印出来看一遍往往就能一眼定位问题。如果你正在做微网群相关的课题或者工程项目我建议先别急着上大规模算例。想办法构造一个3微网×24时段的极简案例先把ATC迭代的每一轮数据打印出来盯着偏差量从大到小收敛的过程建立起对算法的直观感受。这个过程价值巨大磨刀不误砍柴工。另外如果后续要做鲁棒优化或多场景随机优化ATC框架天然支持扩展——只需要把确定性子问题换成场景概率模型即可。希望这篇文章能让你的分布式优化调度代码少走几步弯路。
返回列表