二阶锥松弛化的无功优化,这几年在配电网方向几乎是绕不开的一个词。我最初接触这个题目时,手头拿到的需求也跟这个标题差不多:在配电网里同时考虑储能、有载调压变压器、离散电容器组和静止无功补偿装置,目标是在满足潮流约束的前提下把网损或者电压偏差压到最低。因为模型里混进了整数变量和二阶锥约束,很多刚上手的人第一反应是“这不就是个混合整数非线性规划吗,能解出来吗”。实际做完一遍之后我可以明确说:能解,而且如果建模得当,YALMIP配CPLEX或者Gurobi能跑得很稳。这篇就把我踩过的坑、验证过可行的建模思路、以及那些文档里不会写清楚的细节一次说透。
1. 为什么选二阶锥松弛:从非线性潮流到可求解凸模型的完整逻辑
无功优化的底层约束是潮流方程。在配电网里,我们通常用DistFlow方程来描述支路潮流,这套方程的好处是物理意义直观,坏处是包含电压乘积项和电流平方项,属于典型的非线性非凸问题——节点电压幅值的平方、支路电流幅值的平方和功率项耦合在一起,让整个问题变成了一个难以全局寻优的混合整数非线性规划。
你可能会问:既然有现成的非线性求解器,为什么还要费力做二阶锥松弛?这个问题的答案,我在实际项目中体会很深。配电网无功优化一旦加入储能SOC约束、有载调压分接头档位、电容器投切组数这些离散变量,非线性求解器要么收敛到局部最优,要么干脆不收敛。内点法在处理连续变量时表现不错,可一旦遇到整数变量,分支定界过程中的每次节点求解都要重新处理那个非凸的潮流方程,计算量和数值稳定性都是灾难。二阶锥松弛的引入,本质上是把这个非凸的可行域“放大”成一个凸的锥域,在某种意义上牺牲了模型的精确性,换来了可以全局求解的凸优化结构。
具体来说,DistFlow方程可以做这样一个变换。定义 (l_{ij} = I_{ij}^2) 代表支路电流幅值的平方,(u_i = U_i^2) 代表节点电压幅值的平方,那么原始的欧姆定律和功率平衡方程就可以写成:
- (u_j = u_i - 2(r_{ij}P_{ij} + x_{ij}Q_{ij}) + (r_{ij}^2 + x_{ij}^2)l_{ij})
- (P_{jk} = P_{ij} - l_{ij}r_{ij} - P_{load,j})
- (Q_{jk} = Q_{ij} - l_{ij}x_{ij} - Q_{load,j})
这里第1个式子是从支路首端到末端的电压降落关系,第2、3个式子是节点功率平衡。问题出在哪呢?这些方程里的变量之间还有一个隐式关系:(P_{ij}^2 + Q_{ij}^2 = u_i l_{ij}),这是由视在功率定义推导出来的,而它是个二次等式约束,直接保留会让问题重新变成非凸。二阶锥松弛就是把这个等式约束放松成不等式:(P_{ij}^2 + Q_{ij}^2 \leq u_i l_{ij})。这个不等式在数学上等价于一个标准二阶锥约束,形式如下:
[
\left| \begin{array}{c} 2P_{ij} \ 2Q_{ij} \ u_i - l_{ij} \end{array} \right|2 \leq u_i + l
]
YALMIP里写这类约束时,直接写 (P_{ij}^2 + Q_{ij}^2 \leq u_i \cdot l_{ij}) 就可以,求解器会自动把它识别为二阶锥结构。但我建议在建模时显式创建锥变量,这样既能提高求解效率,也方便后期检查对偶变量。
这里有一个我在实际调模型时反复确认过的关键点:为什么这个松弛在绝大多数配电网算例里是“精确”的?因为目标函数通常是网损最小化或者电压偏差最小化,这类目标会天然地趋向于让不等式取等号。直觉上的解释是:如果某条支路上 (P^2 + Q^2 < u \cdot l),说明线路损耗还有压缩空间,而目标函数里网损项的存在会“推动”系统把松弛量压到零。当然这不是数学意义上的绝对保证,但至少在IEC标准算例和实际馈线数据上,绝大多数支路的锥约束松弛间隙都会收敛到 (10^{-5}) 量级以下。
需要特别说明的是,松弛精确性还受网络结构和负荷条件影响。辐射状网络在无电压约束越限时,松弛基本是精确的;但一旦电压约束进入活跃状态,或者网络中存在环网,松弛间隙就可能拉大。因此我在模型里专门加了锥松弛间隙的统计输出,每次求解完都检查一下最大值有没有超过阈值,这个习惯帮我避开了好几次“结果看似合理但实际物理上不可行”的坑。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 目标函数与约束建模细节:ESS、OLTC、CB和SVC的取舍之道
目标函数的选择直接决定了整个优化问题的导向。在我的代码实现里,目标函数是网损最小加上一系列的惩罚项,写成YALMIP语法大致是:
matlab复制objective = sum(sum(baseMVA * (r_ij .* (P_flow.^2 + Q_flow.^2) ./ (V_mag.^2)))) + ...
weight_volt * sum(sum((V_mag - V_ref).^2)) + ...
weight_oltc * sum(sum(diff(OLTC_tap).^2)) + ...
weight_ess * sum(sum(diff(ESS_soc).^2));
这里有几个容易被忽略的设计决策。网损项用 (P^2 + Q^2) 除以电压平方后再乘电阻,是因为 (I = \sqrt{(P^2 + Q^2)} / U),而网损 (= I^2 R)。但在变量替换之后,(V_mag) 已经不是直接决策变量,而是通过 (u_i) 开根号得到的量,这个非线性操作没法放进锥模型。所以实际建模中,直接用 (l_{ij} \cdot r_{ij}) 的和来表示网损,因为 (l_{ij}) 已经代表了电流幅值
