非线性优化的'导航仪':深入解析 SQP 算法的设计哲学与工程实践
你有没有试过在一个没有 GPS 的城市里找路?可能一开始还信心满满,但很快就会发现——弯道太多、地标模糊、方向感全无。这正是我们在处理非线性优化问题时的真实写照:目标函数像一座起伏不定的山脉,约束条件如同密布的围栏,稍有不慎就掉进局部洼地,再也爬不出来。
而序列二次规划(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)$ 是非线性的,事情就变得棘手了。比如 Rosenbrock 函数那个著名的'香蕉谷',梯度下降法在里面来回震荡几百次都出不来;再比如结构设计中的应力约束,稍微动一下参数,整个系统的响应就剧烈变化。
这类问题广泛存在于机器学习超参调优、机器人轨迹规划、金融投资组合构建等领域。它们的共同特点是:可行域可能非凸、存在多个局部极小值、且边界曲率大。传统方法如梯度下降或牛顿法,在这些场景下要么收敛慢,要么根本找不到好解。
那怎么办?直接求解太难,那就'化整为零'——这也是 SQP 的核心思想。
🤔 想象你在雾中登山,看不清山顶在哪。你能做的,就是在脚下画一个小圆圈,假设这片区域是平滑的,并判断朝哪个方向下坡最快。然后迈出一步,再重复这个过程。这就是 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$ | 要么约束不起作用($\mu\_j=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$ 就像是'影子价格'——告诉你如果稍微放松某条约束,目标函数能改善多少。例如,在资源分配问题中,$\mu\_j > 0$ 意味着第 $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)
i, g (c_eq_grads):
grad_L += lambdas[i] * g(x)
j, h (c_ineq_grads):
grad_L -= mus[j] * h(x)
grad_L

