资讯详情

资讯详情

配电网动态最优潮流SOCP建模与YALMIP实现指南

做完主动配电网方向几年我一直有个感受学术界和工程界之间最常被低估的那条沟不是优化算法本身有多难而是从论文里的算例到我能跑起来的代码中间那个断层。最早接触动态最优潮流DOPFDynamic Optimal Power Flow是在一个含高比例分布式光伏和储能的实际馈线项目里当时用传统内点法求解非线性最优潮流16个节点的小系统算得都发飘更别提24小时时序耦合的规模。后来换成了基于二阶锥规划SOCPSecond-Order Cone Programming的凸松弛模型算例从33节点做到118节点求解时间反而从十几分钟压到了几秒。这篇文章就把这套方法从建模原理、时序耦合处理到YALMIP代码实现和避坑经验完整梳理一遍适合正在入门配电网优化方向的电力研究生也适合想把动态最优潮流真正落到主动配电网场景的工程师。1. 配电网动态最优潮流为什么必须动传统方法的三个失灵现场1.1 传统OPF默认的输电网假设在配电网里处处碰壁教科书里最优潮流OPF那一套早期默认是为输电网设计的。输电网什么特点网架拓扑通常是环网或弱环网线路R/X比很小有功和无功基本可以解耦处理三相也近似认为平衡。这些假设放到配电网身上几乎条条都对不上。配电网是典型的辐射状结构或者说大部分运行方式下是辐射状线路R/X比动辄0.5到3比输电网高一个数量级。R/X大意味着什么有功功率的流动会明显影响电压幅值无功也不再是就地平衡那么简单有功和无功强耦合在一起。我曾经用PQ分解法去解一个含高渗透光伏的33节点馈线潮流结果迭代半天不收敛看着屏幕上波浪形的残差曲线当时就明白配电网的问题不能照搬输电网的思路。这还只是潮流问题。到了最优潮流层面传统非线性规划NLP方法的毛病被放得更大了交流潮流方程本身是非凸的内点法这类局部优化算法对初始点敏感很容易收敛到局部最优而不是全局最优。算例规模一小还好说一旦加进24小时、96个时段的时序耦合变量数量翻几十倍NLP的求解时间呈指数级恶化工程上根本没法用。1.2 动态最优潮流到底动态在哪不是T个静态OPF拼接很多刚接触动态最优潮流的人容易有个误解24个时段算24次静态OPF然后把结果拼起来这不就是DOPF了吗真不是。关键在于时段之间存在状态变量和耦合约束这才是动态二字的本质。最典型的两个耦合源储能和分布式电源。储能系统有一个跨时段递推的荷电状态SOC变量t时刻的充放电决策直接决定t1时刻的SOC这个约束天然跨越时段你没法把每个时段单独拎出来算。分布式电源也一样光伏和风电的出力受预测曲线约束但可调控的DG还有爬坡约束——前一时刻出力是500kW这一时刻不能直接跳到1000kW这又是一个时段间的约束。再加上OLTC有载调压变压器动作次数限制、电容器组投切间隔限制大量离散变量和时序约束搅在一起整个问题一下子变得复杂。所以DOPF的正确打开方式是在一个统一的优化框架里同时处理所有时段的潮流方程、网络约束、储能递推、DG约束和离散变量动作约束。这时问题规模已经远超传统OPF必须找一类结构更好、能保证全局最优的数学模型。1.3 从非凸到凸SOCP一锤定音的价值那二阶锥规划为什么能在这个场景里站住脚一句话它把原来那个非凸、难解、看运气的最优潮流问题改写成了一个凸的、可全局求解、有理论保证的问题。交流最优潮流的非凸性来源核心是支路电流和支路功率之间的等量关系电流幅值的平方等于支路有功平方加无功平方再除以电压幅值平方。这是一个等式约束而且是非凸的等号约束。二阶锥规划的思路是把这个等式放松成不等式也就是允许电流平方大于等于那个比值。别小看这一步改动它直接把问题从非凸扔进了一个凸锥约束里全局最优、多项式时间可解、不依赖初始点这三点对工程落地来说太关键了。更妙的是在辐射状配电网和网损最小化目标下这个放松在绝大多数场景下都是紧的tight也就是最优解会自然落在锥边界上放松前后的最优值相等。这等于说我们用了一个近似模型却往往能拿到原问题的全局最优解性价比极高。后面我会专门讲怎么检验这个紧不紧这是实际项目中必须做的一步体检。2. 二阶锥松弛是怎么一步步化腐朽为神奇的2.1 先摆好模型基础DistFlow支路潮流模型要理解SOC松弛得先熟悉配电网潮流建模里最常用的DistFlow模型。这个模型专门针对辐射状配电网每条支路(i,j)上定义三个关键变量P_ij支路首端流入的有功功率Q_ij支路首端流入的无功功率v_i节点i的电压幅值平方l_ij支路电流幅值平方然后三条基本方程把这几个量串起来节点功率平衡方程。支路i→j的有功和无功一部分被线路阻抗消耗一部分流向节点j后面的所有子支路剩下的等于节点j的净注入功率发电减去负荷。电压降落方程。支路首末端电压幅值平方的关系 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三条方程合在一起DistFlow就是交流潮流在辐射状配电网上的精确描述没有做任何线性化近似这跟很多工程里用的简化潮流模型有本质区别。这一点很重要我们后续做的一切凸松弛起点是一个精确模型不是个拍脑袋的近似。2.2 三个关键替换把非凸等式变成凸锥现在来看SOCP松弛的核心操作。其实就三步第一步把电压和电流的复数量替换成幅值平方量v_i和l_ij。这一步纯粹是变量代换没有损失任何精度。第二步把非凸的电流定义等式 l_ij (P_ij² Q_ij²) / v_i 放松成不等式 l_ij ≥ (P_ij² Q_ij²) / v_i这个不等式的含义很直观允许支路电流幅值平方大于传输当前功率所需的最小值。原问题要求电流必须精确等于这个值松弛后允许电流偏大。第三步把这个不等式改写成标准的二阶锥形式。做一步代数变形l_ij ≥ (P_ij² Q_ij²) / v_i等价于 l_ij · v_i ≥ P_ij² Q_ij²再等价于 (l_ij v_i)² ≥ (l_ij - v_i)² 4P_ij² 4Q_ij²取平方根就得到了标准的二阶锥约束 ||(2P_ij, 2Q_ij, l_ij - v_i)||₂ ≤ l_ij v_i这个形式在优化建模里非常标准YALMIP里一行cone函数就能写进去求解器MOSEK、Gurobi、ECOS都能原生处理。到这一步原本那个让人头疼的非凸等式被一个凸锥约束替代了整个优化模型从NLP变成了SOCP。2.3 几何直觉与精确性松弛为什么往往等于原解理解这个松弛可以借助一个几何直觉。非凸等式 l_ij (P²Q²)/v_i 描述的是三维空间里的一张曲面优化问题的可行域被要求严格落在这张曲面上。而松弛后的锥约束 l_ij ≥ (P²Q²)/v_i描述的是这张曲面上方的整个区域形状上像一个倒扣的锥体或者用一个不太严谨但好记的类比像一个冰激凌筒的内部空间。原来的可行域被要求贴在筒壁上现在允许在整个筒内。那为什么我们不担心最优解跑进筒内部、导致结果不满足原潮流方程这就引出了松弛精确性这个概念。如果SOCP松弛问题求出的最优解恰好落在锥的边界上——也就是电流定义等式重新成立——那这个解同时就是原非凸问题的全局最优解。文献里有理论结果支持在辐射状网络、目标函数是网损的函数、系统满足一定运行条件下SOC松弛是精确的。Farivar和Low那篇关于Branch Flow Model松弛性的工作就是这方向的经典参考。但这里我要泼一盆现实的冷水理论条件在工程现场不一定完全满足。比如目标函数如果是DG发电成本而不是网损、或者某些节点的电压上限约束卡得太紧松弛就可能不紧最优解会偏离真实潮流。所以后面的章节里我会专门讲每次跑完模型都必须做紧性检验这是一个不能跳过的步骤。2.4 为什么网损最小天然利于松弛紧致一个很有意思的细节同样是SOCP松弛目标函数换一下松弛的紧性表现就完全不同。当目标函数是网损最小化时目标表达式里直接包含支路电流平方 l_ij 的加权和 min Σ r_ij · l_ij因为线路电阻 r_ij 是正数优化器有天然的动机把 l_ij 压到最小而锥约束给的又是下界所以 l_ij 会被一路推到锥边界上也就是自动满足了电流定义等式。目标函数自己就在帮忙实现紧性这是网损目标最讨喜的地方。反过来如果目标函数换成DG运行成本、弃置量最小这类东西l_ij 在目标里没有直接出现优化器没有动力把电流压到最小松弛就很容易不紧结果解出来潮流对不上。这一点我在后面调试模型时踩过好几次印象太深了。3. 动态时序耦合建模储能、DG和离散变量的处理细节3.1 目标函数怎么定从单目标到加权多目标动态最优潮流的目标函数选择直接影响松弛紧性和调度结果需要在建模前就想清楚。最常见的几个目标网损最小。前面说过这是SOCP的舒适区目标函数形式是所有时段所有支路电阻乘以电流平方的累加。在含高比例分布式电源的配电网里网损最小化模型往往会得出让DG多出力、减少远端功率输送的调度结果物理上很合理。电压偏差最小。分布式光伏高渗透场景下电压越限是主要矛盾目标函数可以写成所有节点所有时段电压幅值平方与参考值之差的平方和。注意这个目标写成(V_i - V_ref)²是个凸二次函数SOCP模型完全能处理。DG弃置最小。当光伏渗透率极高、消纳能力受限时希望尽量少弃光弃风目标函数写成功率可发值与实际出力之差的总和。实际工程里通常不是单目标而是加权重组合。我的做法是先把各目标的量纲归一化比如网损除以基准网损、弃置量除以总可发量再加权求和。权重怎么定要跟运行需求走没有标准答案但要注意如果网损目标权重太小l_ij 失去被压小的动力可能影响SOC松弛紧性这时候松紧性检验就更重要了。3.2 储能系统的时序递推约束动态建模的核心骨架储能是DOPF里最有代表性的动态元件它的约束包含三个层次。第一层是荷电状态递推方程。假设储能i在t时段的充电功率P_ch,i,t、放电功率P_dis,i,t充放电效率分别为η_c和η_d容量E_cap,i时间步长Δt则 SOC_i,t1 SOC_i,t (η_c · P_ch,i,t - P_dis,i,t / η_d) · Δt / E_cap,i 这个公式是动态的骨架SOC在相邻时段之间像接力棒一样传递把整个优化问题从单断面硬生生拉成了时间耦合的大规模问题。第二层是运行边界。SOC有上下限工程上为了电池寿命通常限制在0.1到0.9之间不建议满充满放。充放电功率也有上下限。这里还有一个工程细节同一时刻不能既充电又放电否则物理上说不通且白白损耗效率。这个互斥约束怎么建模引入一个二进制变量u_i,tu1表示充电、u0表示放电 0 ≤ P_ch,i,t ≤ P_ch,max · u_i,t0 ≤ P_dis,i,t ≤ P_dis,max · (1 - u_i,t)注意一旦引入二进制变量问题类型从SOCP变成了MI-SOCP混合整数二阶锥规划求解复杂度上升一个档次。如果系统里储能数量很多二进制变量会明显拖慢求解速度后面会讲怎么处理。第三层是日始日末SOC约束。调度周期开始时SOC等于初始值SOC_0周期结束时也要求回到SOC_0这样储能不会在整个调度周期里被用干保证日间调度的可持续性。这个约束也顺带避免了模型钻空子把储能SOC在末端压到下限来凑目标函数。3.3 DG出力与爬坡约束别让可调电源想跳就跳分布式光伏和风电在DOPF里通常分为两类一类是不可调的按预测曲线给定出力上限模型里只约束P_DG,i,t不超过预测值另一类是可控DG比如微型燃气轮机、可调光伏逆变器它们有爬坡约束和出力范围约束。爬坡约束的写法很直白 |P_DG,i,t1 - P_DG,i,t| ≤ ΔP_max,i 这个约束跨时段约束了出力变化速率也是DOPF里动态的重要来源。实际数据里燃气轮机的爬坡率可能写着每分钟1MW折算到15分钟一个时段就是每时段15MW换算时别粗心。无功方面DG逆变器通常有功率因数范围比如cosφ在0.95到1之间对应无功与有功的约束是 -tan(arccos φ_max) · P_DG,i,t ≤ Q_DG,i,t ≤ tan(arccos φ_max) · P_DG,i,t 或者直接给无功上下限。写约束的时候要注意有的光伏逆变器具备四象限运行能力无功范围要按厂家参数来不能闭眼套标准值。3.4 网络拓扑与OLTC等离散变量的处理思路DOPF里如果要考虑有载调压变压器和电容器组离散变量就躲不掉了。OLTC的变比是离散的档位比如±8×1.25%对应17个档位。建模上可以用二进制变量选档但直接把17档都建成二进制变量的话约束规模会膨胀得很厉害。我的建议是分两步走第一步先不管OLTC和电容器组只跑一个纯SOCP的DOPF把连续变量下的最优解和计算时间摸清楚。这是基线模型。第二步根据基线结果判断有没有必要上离散变量。如果OLTC的调压作用不明显、电容器组也不多可以考虑把离散变量固定为初始档位变成常数。如果确有必要采用分段线性化或邻域搜索的思路处理先固定档位求连续解再根据电压偏差微调档位迭代两三轮。这样避免了直接求解大规模MI-SOCP工程上稳得多。如果确实需要一步到位求解MI-SOCP那就在建模层面注意控制二进制变量的数量。比如OLTC每个时段的档位用一个连续变量加整数约束建模而不是把每个档位都设成0-1变量变量数量能省一个量级。4. 从公式到能跑的代码YALMIP建模与求解器配置实战4.1 工具链选型为什么推荐YALMIP搭配MOSEK遍历一遍目前常用的优化建模工具我在这个项目里最终锁定的是MATLAB YALMIP MOSEK的组合。YALMIP的优势在于两点一是语法直观SOCP的锥约束可以直接用cone函数表达不像手动建模那样还要自己拼矩阵二是它内置了精确性检验所需要的模型访问接口求解后可以方便地取出原变量值做后验。求解器层面MOSEK是我实测中处理SOCP数值最稳的对锥约束的原对偶内点法实现非常成熟大算例下的收敛速度明显优于很多免费求解器。Gurobi从9.0版本开始也原生支持SOCP如果系统里MIP占比高、需要频繁切分支Gurobi在MI-SOCP上往往比MOSEK更顺。免费场景下可以用ECOS、SDPT3、SeDuMi但33节点24时段的算例跑起来会慢不少适合用来验证小规模理论不适合真的做工程调度。Python环境下则用CVXPY MOSEK的组合建模语法跟YALMIP类似如果你团队的技术栈是Python为主完全可以平移本文的思路。4.2 33节点系统24时段的核心代码建模结构全拆解下面这段代码是DOPF SOCP模型的核心约束结构。数据我用注释说明每一行约束做了什么我都标清楚方便你对照自己的系统数据改。% 动态最优潮流DOPF基于SOCP的建模核心结构 % 需要MATLAB YALMIP MOSEK或Gurobi % 数据约定 % branch: 支路表, 每行[首端节点, 末端节点, r, x] % load_curve: 各节点各时段有功/无功负荷, 维度 [nb, NT] % pv_curve: 各光伏节点各时段可发有功, 维度 [nb, NT] % dt: 时段长度(小时), 如15分钟为0.25 nb 33; % 节点数 nl 32; % 支路数 NT 24; % 时段数 branch ...; % 支路参数按你的系统填 load_curve ...; pv_curve ...; % 决策变量 P sdpvar(nl, NT, full); % 支路有功 Q sdpvar(nl, NT, full); % 支路无功 L sdpvar(nl, NT, full); % 支路电流幅值平方 Vs sdpvar(nb, NT, full); % 节点电压幅值平方 Pg sdpvar(nb, NT, full); % DG有功出力可调部分 Qg sdpvar(nb, NT, full); % DG无功出力 Pch sdpvar(nb, NT, full); % 储能充电功率 Pdis sdpvar(nb, NT, full); % 储能放电功率 SOC sdpvar(nb, NT, full); % 储能荷电状态 u binvar(nb, NT); % 储能充放电互斥标志 1充电 0放电 Constraints []; for t 1:NT % 支路潮流约束 for k 1:nl i branch(k,1); j branch(k,2); rk branch(k,3); xk branch(k,4); % (1) SOC锥松弛核心||(2P, 2Q, L-Vi)|| LVi Constraints [Constraints, cone([2*P(k,t); 2*Q(k,t); L(k,t)-Vs(i,t)], L(k,t)Vs(i,t))]; % (2) 电压降落方程 Constraints [Constraints, Vs(j,t) Vs(i,t) ... - 2*(rk*P(k,t) xk*Q(k,t)) (rk^2xk^2)*L(k,t)]; % (3) 支路电流上限避免松弛后电流虚高 Constraints [Constraints, L(k,t) 0.2]; end % 节点平衡约束 for i 1:nb % 流入发电-负荷储能净放电充电取负 % 这里需要按你自己的支路方向约定累加相邻支路的功率 Constraints [Constraints, ... sum(P(from_idx(i),t)) - sum(P(to_idx(i),t)) - sum(L(from_idx(i),t).*r(from_idx(i),t)) ... Pg(i,t) - load_curve(i,t) Pdis(i,t) - Pch(i,t)]; % 节点电压上下限配电网常见取0.95~1.05 pu Constraints [Constraints, 0.95^2 Vs(i,t) 1.05^2]; % 储能运行边界与互斥约束 Constraints [Constraints, SOC(i,t) 0.1, SOC(i,t) 0.9]; Constraints [Constraints, Pch(i,t) 0, Pch(i,t) 0.5*u(i,t)]; Constraints [Constraints, Pdis(i,t) 0, Pdis(i,t) 0.5*(1-u(i,t))]; % DG出力与无功约束 Constraints [Constraints, 0 Pg(i,t) pv_curve(i,t)]; Constraints [Constraints, Qg(i,t) -0.3*Pg(i,t), Qg(i,t) 0.3*Pg(i,t)]; end % 储能SOC递推跨时段耦合 if t 1 Constraints [Constraints, SOC(:,t) SOC(:,t-1) ... (0.95*Pch(:,t) - Pdis(:,t)/0.95)*dt ./ E_cap]; end end % 日始日末SOC相等 Constraints [Constraints, SOC(:,1) SOC0, SOC(:,NT) SOC0]; % 目标函数全时段网损最小 objective 0; for k 1:nl objective objective branch(k,3) * sum(L(k,:)); end % 求解 ops sdpsettings(solver, mosek, verbose, 2); tic; sol optimize(Constraints, objective, ops); toc; if sol.problem 0 fprintf(求解成功\n); else yalmiperror(sol.info); end这段代码拿过去之后直接跑是跑不起来的因为数据结构需要你自己建模时定义清楚。但模型骨架是完整的你只需要把branch表、负荷曲线、光伏曲线、储能容量按实际数据填进去把节点平衡方程里的from_idx和to_idx按支路方向约定补上。有一个细节我要重点提醒约束集合写成Constraints [Constraints, ...]在循环里反复拼接在变量规模大时效率很差YALMIP内部每次拼接都会复制整个约束集。工程实践中我通常先把所有约束装进一个cell数组最后一次性拼起来Con cell(NT * (nl*3 nb*6), 1); ct 1; for t 1:NT % ...生成约束 Con{ct} Constraints_t; ct ct 1; end Constraints [Con{:}];这个改动在大算例下能省不少内存和时间。4.3 求解器横向对比与效率实测我跑出来的数据同一个33节点24时段算例我分别在几款常见求解器上测过一遍顺便把离散变量的影响也标出来方便你做选型参考。求解器纯SOCP无储能/无离散MI-SOCP含储能互斥和OLTC许可证备注MOSEK约2~4秒约60~180秒商业/学术免费SOCP数值最稳首选Gurobi 10约3~6秒约40~120秒商业/学术免费MI-SOCP分支能力强ECOS约20~40秒不支持MIP免费开源适合小规模验证SDPT3约几分钟不支持MIP免费老牌效率偏低SeDuMi约几分钟不支持MIP免费数值偶尔飘这个数据是纯SOCP所有储能充放电状态预先固定的前提下。一旦把互斥二进制变量加进去变成MI-SOCP求解时间翻几十倍是常态因为分支定界要反复求解SOCP子问题。如果你的系统节点数超过100、时段数又是96我强烈建议先不要让所有储能都带二进制变量可以通过日前预调度把部分储能的充放电时段先固定下来。4.4 数据预处理标幺化和场景曲线建模前的数据预处理做过实际项目的都懂这块没做好后面全白搭。第一件事是标幺化。配电网原始数据参差不齐电压有的是12.66kV有的是10kV功率有的是kW、有的是MW直接拿原始数值建模会让约束矩阵条件数极差求解器容易数值振荡甚至报无解。统一基准功率取1 MVA对33节点系统基准电压取12.66kV。这样电压变量在0.9~1.1附近支路功率在0~1附近约束矩阵数值才是良态的。第二件事是负荷曲线和光伏曲线的构造。典型日负荷曲线一般按24小时或96个15分钟时段给出比例系数乘以节点基准负荷得到各时段实际值。光伏曲线按晴日、多云、阴天几个典型场景分别生成调度结果对场景非常敏感工程上通常要跑多个场景做鲁棒性校验而不是只跑一个最典型的日曲线。第三件事是预测误差的裕度。现场数据不会跟预测完全一致约束别建得刚贴边比如电压上限约束别卡在1.05pu的极限值给自己留0.5%~1%的安全裕度否则调度结果拿到现场一执行就越限。5. 松弛紧性检验与数值求解的隐蔽陷阱5.1 松弛紧性检验每次求解后必须做的体检模型求解不是终点紧接着要做的是检查SOC松弛到底紧不紧。这一步不做你的最优解很可能根本不是原问题的可行解。检验方法也很直接求解完成后取出所有支路所有时段的P、Q、L、Vs变量计算每一条支路的原等式残差rel_gap |L_ij · Vs_i - (P_ij² Q_ij²)| / (P_ij² Q_ij²)然后统计全时段的最大值和平均值。代码只要几行gap_all zeros(nl, NT); for k 1:nl for t 1:NT i branch(k,1); gap_all(k,t) abs(L(k,t)*Vs(i,t) - (P(k,t)^2Q(k,t)^2)) / (P(k,t)^2Q(k,t)^2 eps); end end max_gap max(gap_all(:)); fprintf(最大相对对偶间隙: %g\n, max_gap);我的经验阈值是标幺化之后max_gap小于1e-4就可以认为松弛紧、解是可信的如果到了1e-3甚至更大那这个最优解很可能是废的。一旦发现松弛不紧按这个顺序排查原因第一看目标函数里是不是没有足够的压小L的动力。如果目标函数改成弃置量最小或者综合费用要格外警惕。解决办法是给L加一个小权重惩罚项比如目标加上0.001倍的ΣL诱导松弛往边界靠但注意权重不能太大否则就改变了原目标。第二看电压上限约束是否过紧。节点电压上限被顶到边界时SOC松弛很容易不紧这时候考虑把上限放宽一点点再试。第三看是否某些支路的电流上限约束卡得过死导致锥内部解成了被迫的最优。电流上限该放宽就放宽。第四检查模型是不是漏掉了某个电压下限约束导致的病态解。给Vs加一个很小的下界比如0.01²能挡掉数值上的一些奇葩分支。5.2 数值求解的三个隐蔽陷阱这几条都是我在实际算例里实打实踩过的每一条都花了我不少时间排查。陷阱一忽略了VS隐含的正性条件。电压幅值的平方理论上必须大于零。但求解器眼里只有不等式约束如果模型里没有显式给Vs一个正下界内点法可能会在迭代中试探到负极值区域导致解的物理意义崩溃。加一条Vs 0.01^2的约束几行字的事能把一堆莫名其妙的数值问题挡在门外。陷阱二储能同时充放电没有彻底堵死。二进制互斥约束写了看起来没问题但因为求解器对二进制变量的容差完全可能出现Pch和Pdis同时为非零小值的情况。检查解的时候如果发现某个时段Pch和Pdis同时大于0.001说明互斥约束的建模间隙太大。处理办法是把互斥约束改成Constraints [Constraints, Pch(i,t) 0.5*u(i,t), ... Pdis(i,t) 0.5*(1-u(i,t)), Pch(i,t) Pdis(i,t) 0.5];再多加一道两个变量之和的上限把重叠部分直接压掉。陷阱三求解器默认容差对大算例不够用。MOSEK跑33节点纯SOCP没问题但跑到118节点96时段默认容差下的报错率会明显上升。我的习惯是把MOSEK的MSK_DPAR_INTPNT_CO_TOL_REL_GAP设到1e-7甚至1e-8同时打开预求解收敛效果会有质的改善。当然容差设太小求解时间会变长需要自己权衡。5.3 从33节点到118节点规模化时会遇到什么规模一旦做大咱们前面说的所有问题都会被放大以下几点是我在扩展算例时的实操经验。首先变量规模是呈倍数膨胀的。24时段33节点系统的变量数大约在几千这个量级而96时段118节点系统很容易冲破十万变量。这时候在MATLAB里每秒钟重复拼接约束集的写法会直接卡死必须改用cell数组累积约束的写法这也是前面代码里特意提到的点。其次能砍的离散变量就砍。OLTC档位、电容器组这些设备如果每个时段都放开整数变量MI-SOCP分支定界会跑到天荒地老。工程上我喜欢先固定离散变量跑一个纯SOCP然后把离散变量按结果微调一两次效果和全局整数优化差距很小计算时间却能节约一个数量级。这个技巧在调度类项目里属于压箱底的优化手段。第三充分利用配电网辐射状的结构特点。很多支路之间并没有通过同一节点耦合约束本身就有天然的稀疏结构求解器如果支持稀疏矩阵就有利。在YALMIP里确保所有数据都以稀疏格式传入不要用full矩阵否则内存直接翻几倍。最后如果算例实在太大可以用时段分解的思路先把储能SOC作为伪影子价格解耦出各时段的子问题迭代求解。这属于更进阶的方法我自己的经验是先确认单机直接求解确实不行了再上这类分解算法不要一上来就搞复杂架构否则调试成本反而更高。6. 跑完整个流程后我对这套方法的几点实在体会最后聊几句我这个过来人的体会比较散但都是实操中沉淀下来的。第一个体会是SOCP在处理配电网DOPF问题时确实是目前性价比最高的选择。它不像线性化模型那样牺牲精度又没有非线性规划那些初值敏感、局部最优的老毛病工程实现门槛还低——你能写MATLAB、会用YALMIP基本半天就能把模型搭起来。第二个体会是永远不要假设松弛一定紧。即使你的系统是辐射状、目标函数是网损这种友好设定也可能会因为某个约束卡得太死而出问题。我自己的习惯是把紧性检验写成求解后的固定步骤不管是不是调试状态每次都跑一遍这是代码级别的纪律。第三个体会是算例规模不是越大越好。论文里跑个118节点96时段很好看但工程调度现场数据质量往往撑不起那么细的模型。我经常用96时段模型做离线分析但真正进现场调度系统时反而用24时段的日调度模型加15分钟滚动修正鲁棒性更好。DOPF最终的归宿是给实际运行决策提供依据模型复杂度应该匹配数据质量和控制能力这个度要把握好。最后分享一个几乎所有项目都会用到的小技巧在目标函数里额外加一个极小权重的电流平方和惩罚项比如objective objective 1e-4 * sum(sum(L));这行代码能显著提升SOC松弛的紧性却又几乎不影响原目标函数的最优值是我在建模调试中屡试不爽的安全垫。配电网动态最优潮流这个方向理论和工程之间的跨度不小但一旦把SOCP这条链路走通后面无论是加储能、加多场景还是加不确定性都只是在这个框架上做增量。希望这篇文章能让你的第一步迈得比我当初更顺。
觉得有用,分享给同行:

为您的企业打造数字门面

稳重轻奢商务风格,端正雅致视觉,长效耐看不易过时。

立即咨询 →