二次序列规划(SQP)算法详解与实战
简介
二次序列规划(SQP)是一种用于求解带约束非线性优化问题的高效迭代算法,广泛应用于工程、经济、物理和科学计算等领域。该方法通过在每一步迭代中构建目标函数的二次近似和约束的一阶线性化,将原问题分解为一系列二次规划子问题,逐步逼近最优解。本文深入解析 SQP 的核心思想、关键步骤及 Hessian 矩阵近似技术,并介绍 BFGS、L-BFGS 等常用改进策略,结合实例展示其实际应用效果。
SQP 算法的设计哲学与工程实践
在处理非线性优化问题时,目标函数像一座起伏不定的山脉,约束条件如同密布的围栏。序列二次规划(Sequential Quadratic Programming, SQP)通过每步重新绘制局部地图,用数学方式确定最优搜索方向,避免陷入局部极小值。
从 KKT 条件到搜索方向:SQP 的底层逻辑基石
什么是非线性优化?为什么这么难?
我们面对的问题通常形式如下:
$$ \min_x f(x) \quad \text{s.t.} \quad c_i(x) = 0,\ c_j(x) \geq 0 $$
一旦 $f(x)$ 或 $c(x)$ 是非线性的,问题变得棘手。这类问题广泛存在于机器学习超参调优、机器人轨迹规划、金融投资组合构建等领域。它们的共同特点是:可行域可能非凸、存在多个局部极小值、且边界曲率大。传统方法如梯度下降或牛顿法,在这些场景下要么收敛慢,要么根本找不到好解。
SQP 的核心思想是'化整为零':在脚下画一个小圆圈,假设这片区域是平滑的,判断朝哪个方向下坡最快,然后迈出一步,重复这个过程。即局部近似 + 迭代逼近。
KKT 条件:不是所有点都能当'终点'
在无约束优化中,我们只需要让梯度为零即可。但在有约束的情况下,一个点要想成为候选最优解,必须满足更严格的 Karush-Kuhn-Tucker(KKT)条件。
| 条件类型 | 数学表达 | 物理意义 |
|---|---|---|
| 平稳性 | $\nabla_x \mathcal{L}(x,\lambda,\mu)=0$ | 梯度力与约束反作用力平衡 |
| 原始可行性 | $c_i(x)=0$, $c_j(x)\geq0$ | 解必须位于可行域内 |
| 对偶可行性 | $\mu_j \geq 0$ | 不等式约束乘子非负 |
| 互补松弛 | $\mu_j c_j(x) = 0$ | 要么约束不起作用,要么紧致 |
其中,拉格朗日函数定义为: $$ \mathcal{L}(x, \lambda, \mu) = f(x) + \sum_{i \in \mathcal{E}} \lambda_i c_i(x) - \sum_{j \in \mathcal{I}} \mu_j c_j(x) $$
这里的 $\lambda_i$ 和 $\mu_j$ 就像是'影子价格'。
import numpy as np
def lagrangian_gradient(x, lambdas, mus, f_grad, c_eq_grads, c_ineq_grads):
"""
计算拉格朗日函数在某点的梯度
参数说明:
x: 当前变量向量 (n,)
lambdas: 等式约束乘子向量 (m_eq,)
mus: 不等式约束乘子向量 (m_ineq,)
f_grad: 目标函数梯度函数 handle -> R^n
c_eq_grads: 等式约束梯度列表 [R^n]
c_ineq_grads: 不等式约束梯度列表 [R^n]
"""
grad_L = f_grad(x)
for i, g in enumerate(c_eq_grads):
grad_L += lambdas[i] * g(x)
j, h (c_ineq_grads):
grad_L -= mus[j] * h(x)
grad_L

