ARTICLE · INTELLIGENCE

战地情报 · 详情页

来自尧图项目组的一线实战观察与深度解析

配电网最优潮流二阶锥松弛的Matlab+YALMIP实现全解析

配电网最优潮流二阶锥松弛的Matlab+YALMIP实现全解析 最近在做配电网最优潮流计算相关的仿真工作把二阶锥松弛Second-Order Cone RelaxationSOCR用在配电网最优潮流Optimal Power FlowOPF里用Matlab加YALMIP实现了整套流程。这个方向这几年在电力系统优化领域尤其热核心原因很简单配电网潮流问题天然是非凸的传统非线性规划求解慢、还不保证收敛到全局最优而二阶锥松弛能把一大类非凸问题转成凸问题既保证收敛又能在多项式时间内求出接近全局最优的解。这篇就围绕这个项目的完整实现过程把思路、数学推导、代码结构和调试心得全部拆开聊适合正在做配电网优化、分布式电源接入、微电网调度相关研究的同学参考也适合刚接触凸优化在电力系统应用的同学入门。我自己第一次接触这个题目时也踩了不少坑从建模时变量选取搞混到松弛不紧导致结果失真再到求解器选型不当导致内存爆炸零零散散折腾了大半个月。回头再看这个项目其实链条非常清晰只要把“为什么能松弛”“松弛后怎么做”“怎么验证松弛有效性”这三件事搞明白整体实现就很顺。1. 先从问题说起配电网最优潮流的痛点在哪最优潮流在输电领域发展了这么多年已经非常成熟。但把传统OPF模型直接搬到配电网里问题立刻暴露。最直观的差别是拓扑结构输电网是环网配电网几乎全是辐射状单电源树形结构传统的基于网架的潮流模型在配电网里要重新适配。再加上配电网的R/X比偏高线路电阻不能再忽略潮流方程里的二次项和非线性耦合项更难处理这就让配电网最优潮流成为一个典型的非凸二次约束规划问题Quadratically Constrained Quadratic ProgramQCQP。1.1 传统OPF模型在配电网上的“水土不服”传统OPF的目标函数通常是最小化发电成本或网损约束包括节点功率平衡、支路潮流方程、电压幅值上下限、发电机出力上下限等。在输电网中因为电压等级高、线路电抗远大于电阻可以引入直流潮流简化把问题近似成线性规划来解。但配电网不行如果用电网算例来做R/X比大约在0.2到1.2之间直流潮流那种忽略电阻和电压无功耦合的假设完全不成立。还拿直流法来近似算出的网损会严重失真节点电压也几乎不对。交流潮流模型下配电网OPF的数学表达要比直流情形复杂得多。潮流方程里电压、电流、功率彼此耦合而且节点电压平方项出现在多个约束里目标函数又是二次的整个问题是非凸的直接丢给传统非线性规划求解器能解但心里没底因为局部最优和全局最优可能差很远。常规非线性规划算法如内点法对初值极其敏感同一个算例换一个初始点就可能得出另一组机组出力和电压分布这种不稳定性在做方案对比时极难接受。1.2 想用暴力搜索维数灾难马上教你做人有不少人刚开始不理解为什么要费劲做凸松弛想着配电网节点也不算多是不是可以用枚举法或者随机搜索暴力解决。假定一个33节点算例其中有分布式电源的节点有5个每个电源出力连续可调哪怕只把每个出力的可行域离散成100个点组合数就是100的5次方也就是100亿种情况光枚举一遍就够喝一壶的。再加上全网各节点电压互相耦合每评估一种情况都要做一次完整的潮流计算这个计算量在实际工程中完全不可接受。所以问题的本质很清楚既要保留交流潮流的物理精度又要让求解过程稳定高效。这时候凸优化工具就派上用场了。如果能把非凸问题转化成凸问题那么局部最优就是全局最优求解器也能给出确定性的收敛保证。二阶锥松弛正好提供了一座从非凸到凸的桥。2. 二阶锥松弛到底解决了什么一个看得见的核心逻辑二阶锥松弛不是新概念在数学优化领域已经积累了很多年。把它用到配电网最优潮流里最关键的一步是变量替换把那几个困扰大家的非线性耦合项换成新变量硬生生把一个非凸可行性约束变成线性和凸锥约束的组合。我建议理解这个算法的路径分三层层层递进先看原问题为什么非凸再看变量替换怎么把非线性拆开最后看二阶锥约束为什么是凸的以及它跟原问题差了什么。2.1 非凸性源自哪里Bus注入模型里的二次耦合如果直接用最常见的节点电压相角形式写配电网潮流每条支路潮流是两侧节点电压幅值乘积和相位差的余弦正弦的耦合函数计算式包含乘积项和三角函数项。这种情况下目标函数和约束里有大量形如 |Vi||Vj|cos(θi-θj) 的项这不是凸函数。整个可行域不是凸集优化性质很差。在配电网优化里业界普遍推崇另一种建模方式叫DistFlow模型。这个模型由支路而不是节点来刻画潮流每条支路上的潮流是前向递推的特别贴合辐射状配电网的特性。DistFlow方程把直接依赖于电压相角的正弦余弦项消掉了但代价是引入了电压平方和电流平方的乘积关系约束里有 l_ij (P_ij² Q_ij²)/v_i 这种形式v_i 是节点i的电压幅值平方l_ij 是支路电流幅值平方。这个等式约束分子的平方和形式是凸的分母是线性变量整体却是非凸等式。2.2 DistFlow模型与变量替换的数学推导写一下DistFlow的基本方程。对一条从节点i流向节点j的支路ij定义P_ij、Q_ij 为支路首端有功和无功潮流v_i |V_i|² 为节点i电压幅值平方l_ij |I_ij|² 为支路电流幅值平方那么配电网DistFlow方程可以写为 P_ij P_jk P_load_j R_ij * l_ij有功平衡从节点j流向所有下游支路之和加负荷 Q_ij Q_jk Q_load_j X_ij * l_ij无功平衡 v_j v_i - 2(R_ij * P_ij X_ij * Q_ij) (R_ij² X_ij²) * l_ij电压降方程 其中l_ij (P_ij² Q_ij²) / v_i这是连接功率流和电流的物理关系式。这套方程的好处是如果不看最后一个等式前三条约束其实是线性的。真正让问题变非凸的只有l_ij的等式定义。于是很自然想到把等式松弛成不等式 l_ij ≥ (P_ij² Q_ij²) / v_i 会怎么样这一步的物理意义很直白支路电流幅值平方允许不小于由功率流决定的最小值相当于放宽了电流与功率流的绑定关系。问题在于为什么要放宽而且是“大于等于”而不是“小于等于”原因稍微推一下就清楚目标函数是网损最小而网损和支路电流平方正相关求解器在最小化目标时会把l_ij往下压如果可行域允许l_ij取更大值它反而会主动选最小的l_ij。也就是说在网损最小这个目标驱动下松弛后的不等式在最优解处自动取等号不会引入松弛误差。2.3 二阶锥约束的标准形式与Matlab表达不等式 l_ij ≥ (P_ij² Q_ij²) / v_i 本身还不是标准的二阶锥形式需要做个等价变形。用v_i乘两边得到 l_ij * v_i ≥ P_ij² Q_ij²。然后把四项组合成欧几里得范数的形式。定义向量 z [2P_ij; 2Q_ij; l_ij - v_i]则原不等式等价于 向量的二范数 ||z||₂ ≤ l_ij v_i展开验证一下就明白 ||z||₂² 4P_ij² 4Q_ij² (l_ij - v_i)² (l_ij v_i)² l_ij² 2l_ijv_i v_i² 因为 l_ijv_i - P_ij² - Q_ij² ≥ 0整理后左边≤右边成立。这就是二阶锥约束的典型表达式。在YALMIP里写这约束很直接直接用cone命令就能表达标准二阶锥cone([2*P_ij; 2*Q_ij; l_ij - v_i], l_ij v_i)到这一步整个二阶段计划就非常清晰了。原来非凸的QCQP问题被转成了一个标准的二阶锥规划问题SOCP全部约束为线性等式加二阶锥不等式目标函数是线性的网损表达式。SOCP是凸优化的一种经典内点法能保证收敛到全局最优解Matlab里的YALMIP配合开源求解器可以直接算不需要昂贵的商业求解器也能完成项目。3. Matlab代码实现全流程解析整个项目的核心是Matlab代码实现代码结构直接影响后续扩展和调试效率。我要先定整体架构再细拆每个函数的输入输出和关键约束写法最后讲求解器调用方式。这套流程做完你完全可以在这框架上增加分布式电源优化、储能调度或无功优化等更复杂目标。3.1 整体架构从数据输入到结果输出的模块划分我建议主程序按固定四步走方便定位问题。第一步定义配网基础数据第二步建立优化变量第三步写约束和目标函数第四步调用求解器并输出结果。每部分单独放一个脚本或函数模型参数、拓扑数据和算法配置别混在同一个文件里否则修改节点参数时容易漏改。推荐的文件组织结构opf_socr_main.m -- 主脚本 case33_radial.m -- 配电网参数定义节点、支路、负荷、DG出力 build_distflow.m -- 构建DistFlow约束函数 plot_result.m -- 电压幅值、网损等结果可视化这个结构迭代调参非常快。改算例只动case函数调整算法配置只改主脚本里对应的段。这里有几个数据定义的关键点。节点数据里要给出每节点的有功负荷和无功负荷首节点通常是上级电网馈入点当作平衡节点处理电压幅值固定。支路数据要给出首末端节点编号、电阻、电抗。分布式电源数据则给出接入节点编号和有功出力范围。在实际项目里分布式电源通常被建模为PQ节点或PV节点但因为配电网电压控制能力弱很多优化模型里简化为出力可调的负负荷即有功出力和无功出力都在给定范围内。3.2 YALMIP建模关键代码段拆解变量定义要区分两类线性变量和二阶锥变量。电压平方v_i是线性非负变量支路电流平方l_ij也是线性非负变量支路有功P_ij和无功Q_ij是自由实数变量但在辐射状网络中方向已定为从首端流向末端。在Matlab里用sdpvar定义即可。核心代码段如下% 电压幅值平方变量 v v sdpvar(nbus, 1); % 支路有功和无功变量 P sdpvar(nbranch, 1); Q sdpvar(nbranch, 1); % 支路电流平方变量 l l sdpvar(nbranch, 1);变量定义后写约束。约束分为四组节点功率平衡约束、支路电压降约束、二阶锥松弛约束和运行安全约束。节点功率平衡约束是DistFlow模型递推关系的核心。对每个节点j流入该节点的支路功率加上注入功率DG出力等于流出该节点的支路功率之和再加负荷。实现时不需要写电网导纳矩阵只需要基于支路首末端节点索引做聚合。constraints []; for k 1:nbranch i branch(k, 1); j branch(k, 2); % 线路压降方程 constraints [constraints, v(j) v(i) - 2*(R(k)*P(k) X(k)*Q(k)) (R(k)^2 X(k)^2)*l(k)]; % 二阶锥约束 constraints [constraints, cone([2*P(k); 2*Q(k); l(k) - v(i)], l(k) v(i))]; end再加上节点电压上下限约束、DG出力范围和支路电流上限约束最后定义目标函数。网损是支路电流平方乘以电阻之和表达式objective sum(R .* l);这里要注意网损目标函数使求解器有动力把l压到最小值从而保证松弛在最优解处取等这正是松弛有效性的关键所在。3.3 求解器选型与参数设置求解SOCP问题的经典开源求解器有SDPT3和SeDuMi两者都是内点法求解器适合中小规模算例。如果想提速可以配置Mosek但那个是商业软件部分学校有学术授权个人可以考虑开源方案。YALMIP的调用统一接口是这样的ops sdpsettings(solver, sedumi, verbose, 1, debug, 1); optimize(constraints, objective, ops);这里比较推荐把debug开关打开YALMIP在建模阶段会检查约束是否线性、是否为有效的二阶锥表达式。很多新手写的约束因为变量是嵌套平方或指数形式YALMIP无法识别成有效二阶锥最后会报“无法处理模型类型”一类的错误。打开debug能快速定位哪一行约束格式出了问题。求解完成后还需要从求解器结果中提取变量值V_square value(v); P_flow value(P); network_loss value(objective);提取出来后画节点电压分布图或者对比线路传输功率和容量约束这就进入结果分析阶段了。4. 算例测试与结果分析到底有没有效果光把代码跑通不叫完成项目验证结果合理才是关键。测试阶段最重要的三件事松弛紧性验证、电压约束满足情况和与常规潮流计算结果的交叉验证。4.1 测试环境与标准算例测试用的算例我推荐经典33节点辐射状配网这个算例在配电网优化领域基本等同于“hello world”。它有33个节点、32条支路总负荷大约是3715 kW加2300 kvar。初始状态下没有分布式电源接入时系统网损大约在200 kW左右这个数值是公开资料里反复出现过的可以用作基准程序跑出来的结果如果和这个数差太远基本可以断定建模或求解环节出错了。在加分布式电源之前先用二阶锥松弛跑一遍基础网络。这时最优化的目标是最小化网损由于没有DG实际上最优控制手段只有根节点电压和线路上的无功流动。把根节点电压设为1.0 pu电压下限设为0.95 pu上限设为1.05 pu。计算得到的网损和不加优化的潮流网损接近但略低这是因为优化器会调整全网无功分布让无功尽量就地平衡而不是从根节点长距离输送。这个现象在结果分析时很明显末端节点电压相比初始潮流有所抬升说明无功优化确实起作用了。4.2 结果对比与松弛紧性验证加DG后算例更有意思。在节点18、22、25和33分别接入有功出力范围在0到500 kW的分布式电源单位功率因数运行即不注入无功。优化后网损显著下降具体数值很大程度取决于DG的出力分配最终结果会是多个DG都满发或接近满发因为对于网损最小目标而言提高本地供电比例减少远距离输电总是有利的。验证松弛紧性是这个项目里不能跳过的步骤。紧性指的是松弛后的二阶锥约束在最优解处取等号即 l_ij (P_ij² Q_ij²) / v_i 精确成立。检验方法很简单取最优解处的value(P)、value(Q)、value(v)和value(l)对每条支路计算松弛间隙也就是右端相减的差值。数值上是零说明松弛紧模型正确。如果某些支路的间隙不是零就要怀疑目标函数里是不是遗漏了与电流相关的惩罚项或者网络存在重载导致电流约束提前激活从而让电流平方强制高于功率流所需的最小值。有一次实际算例中某条支路电流上限刚好卡在临界值上导致松弛不紧结果里这条支路的电流平方明显大于功率流对应的最小值。后来把目标函数里加了线路电流上限约束的惩罚才处理干净。这个问题启示很重要松弛紧性不能想当然每跑一个算例都要检查。最终把SOCP求解结果与Newton-Raphson潮流计算做交叉验证。用优化后的电源出力作为已知注入输入到常规潮流计算程序里看得到的节点电压分布是否与SOCP优化的电压变量一致。两者误差应该在1e-4以下否则说明潮流模型本身有出入比如负荷模型或变压器分接头设置不一致这类问题只通过优化结果很难发现交叉验证一下就可以暴露。5. 常见问题与调试经验实录整个项目过程中踩过的坑不少有些坑属于“座标不对类型”有些坑属于“数学建模有误类型”还有些属于求解器使用问题。这部分把高频问题整理成速查表附带我自己的排查心得。问题现象根本原因解决方案YALMIP报错“无法处理模型类型”约束中含有非凸非二次表达式无法识别为SOCP检查是否漏掉变量替换所有二次项要用v/l/P/Q表达求解结果网损明显偏大目标函数未正确包含全部支路电阻乘电流平方项核对目标函数表达式是否漏了支路索引最优解处二阶锥约束不紧支路电流上限约束主动激活或目标中缺少电流惩罚检查电流约束冗余性调整目标函数求解器内存溢出变量规模太大或用了SEQUENTIAL的求解设置改用sedumi求解器并清空YALMIP缓存节点电压优化后反而低于潮流计算值分布式电源被建模为恒定有功输出未考虑无功支撑调整DG无功出力范围加入电压调节能力5.1 求解器报错与收敛性问题YALMIP报错大多来自约束表达式中变量嵌套。比如直接写了 P(k)^2/Q(k)这就超出了二阶锥框架的语言范围YALMIP非要识别为多项式模型最终落入非线性规划的范畴不再是SOCP。正确做法是引入辅助变量l_ij来承载二次信息。收敛性问题常在多DG接入时出现。SDPT3对变量尺度比较敏感如果电压单位用V而非kV数值会差好几个数量级求解器迭代矩阵条件数很大收敛变慢甚至失败。实际项目中我把所有电压都用标幺值pu功率用kW精度控制在1e-4就没再遇到收敛问题。5.2 关于松弛紧性的判断松弛紧性是整个二阶锥方法能不能落地的关键。凸松弛一旦不紧优化结果就不是原问题的精确解而是原问题的一个下界直接用于工程分析可能得出“可行但非最优”的错误结论。判断紧性的快捷方式除了看间隙数值还可以看支路利用率。如果最优解中某条支路电流刚好等于其上限那么这条支路的二阶锥约束极大概率是紧的但如果有DG出力集中在某节点导致潮流强行很大也可能出现紧性破坏。经验法则是目标函数必须对l有单调压力网损目标天然满足这一点如果目标改成购电成本最小且没有网损惩罚项就要额外小心因为目标可能对l不敏感松弛后的解会有随机偏移。5.3 性能优化与算法加速小技巧33节点算例用SDPT3求解基本是秒级完成但如果扩展到几百节点、上百DG耗时就会指数上升。加速思路有三个一是固定DG接入方案先求最优潮流的近似解作为迭代初值二是划分电力子网先对子网内部做SOCP再协调边界变量三是考虑使用更高效的并行内点求解器常见商业求解器在此类问题上优势明显。还有一个实用主义的小技巧先用最小的3节点或5节点手算算例把整条链路调通再进行大算例。小算例能快速暴露变量索引错误和约束维度不匹配的问题调试效率远高于直接跑33节点。我早期试过直接跑标准算例一旦报错根本无法定位是哪条线路约束出了问题后来退回去先用5节点手推一遍十分钟就把索引关系理清了。6. 进阶扩展方向从静态最优潮流到动态调度项目做到这里二阶锥松弛解决配电网最优潮流问题的主流程已经全部打通。顺着这个基础可以继续扩展几个应用方向很多都是当前配电网研究的热点而且不需要推翻现有代码框架只需要加变量、加约束。一个方向是分布式电源的容量规划。在现有OPF框架里把DG出力变量改成待规划容量目标是投资收益最大化约束除了潮流约束之外还加年运行小时数约束仍然能保持SOCP结构。另一个方向是配电网重构也就是通过调整线路开关状态来改变网络拓扑配合二阶锥松弛能做混合整数二阶锥规划MISOCP在YALMIP里需要声明整数变量求解器配上支持整数规划的版本。储能调度也可以接进来。储能装置引入储能状态变量和时间耦合约束问题从静态SOCP变成多时段SOCP约束矩阵会更大但结构基本不变。只要时间粒度取合适比如每15分钟一个断面24小时内变量数量也只是线性增加SDPT3处理起来依然可行。我个人在实际使用里的体会是二阶锥松弛这个方法在配电网优化里之所以流行不只是因为它数学漂亮更因为它给了工程师一个“可以跑的凸优化模型”。相比黑盒的非线性求解器SOCP的可解释性强约束松不松、紧不紧都有明确验证手段。对于工程应用来说这种可验证性比分毫必争的“最优值”更重要。最后分享一个调试小技巧写代码时把v、l这些变量名取得短一点没关系但一定要在注释里写明物理含义不然三周后再打开自己的脚本很可能想不起来哪个变量是电压平方、哪个是电流平方。这个项目我经历过好几次“变量命名一时爽隔周调试火葬场”的窘境后来养成习惯每个sdpvar定义下面都挂一行注释才彻底告别这个麻烦。
RELATED READING

延伸阅读

更多一线实战笔记与深度复盘,助您持续精进