基于近似Hessian的序列二次规划算法(SQP with Approximate Hessian)进阶题
我将为你讲解一个关于“基于近似Hessian的序列二次规划算法”的进阶题目,侧重于如何处理大规模问题中精确Hessian矩阵计算代价高昂的挑战。
题目描述
考虑以下非线性规划问题:
最小化 \(f(x)\)
满足 \(c_i(x) = 0, \quad i = 1, \ldots, m\)
以及 \(c_i(x) \geq 0, \quad i = m+1, \ldots, m+p\)
其中 \(x \in \mathbb{R}^n\),且 \(n\) 很大(例如 \(n \geq 1000\)),\(f(x)\) 和 \(c_i(x)\) 都是二阶连续可微的。精确计算目标函数和约束的Hessian矩阵(二阶导数矩阵)在每一次迭代中计算代价过高,甚至因问题规模而不可行。请设计并详细解释一个 基于近似Hessian的序列二次规划(SQP)算法 来解决此类大规模问题。你的讲解需覆盖:1) 算法核心思想的动机;2) 如何构造并更新Hessian矩阵的近似;3) 完整的算法步骤;4) 关键参数的选择与收敛性保障策略。
解题过程循序渐进讲解
步骤1:理解问题与SQP算法回顾
我们面临的是一个带等式和不等式约束的非线性规划问题。序列二次规划(SQP)是解决此类问题的经典方法,其核心思想是:在当前迭代点 \(x_k\),通过求解一个二次规划(QP)子问题来获得搜索方向 \(d_k\),然后沿该方向进行线搜索更新迭代点。
标准的QP子问题形式为:
最小化 \(\nabla f(x_k)^T d + \frac{1}{2} d^T B_k d\)
满足 \(c_i(x_k) + \nabla c_i(x_k)^T d = 0, \quad i = 1, \ldots, m\)
以及 \(c_i(x_k) + \nabla c_i(x_k)^T d \geq 0, \quad i = m+1, \ldots, m+p\)
其中 \(B_k\) 是拉格朗日函数 \(L(x, \lambda) = f(x) - \sum_{i=1}^{m+p} \lambda_i c_i(x)\) 关于 \(x\) 的Hessian矩阵 \(\nabla_{xx}^2 L(x_k, \lambda_k)\) 或其近似。
关键点:在标准SQP中,\(B_k\) 是精确的Hessian矩阵。然而,对于大规模问题:
- 计算精确的 \(\nabla_{xx}^2 L\) 需要计算所有二阶导数,计算复杂度为 \(O(n^2)\) 甚至更高。
- 存储 \(n \times n\) 的稠密矩阵 \(B_k\) 需要 \(O(n^2)\) 内存,当 \(n\) 很大时可能超出内存限制。
因此,我们必须用 近似Hessian矩阵 \(B_k\) 来代替精确Hessian。
步骤2:近似Hessian矩阵的构建与更新策略
我们的目标是用一个计算和存储更高效的矩阵 \(B_k\) 来近似 \(\nabla_{xx}^2 L(x_k, \lambda_k)\),同时保持算法的收敛性。常用策略是采用 拟牛顿法(Quasi-Newton Methods) 的思想。
具体来说,我们要求 \(B_{k+1}\) 满足拟牛顿方程(也称为割线方程):
\[ B_{k+1} s_k = y_k \]
其中:
- \(s_k = x_{k+1} - x_k\)(决策变量的变化量)
- \(y_k = \nabla_x L(x_{k+1}, \lambda_{k+1}) - \nabla_x L(x_k, \lambda_{k+1})\)(拉格朗日函数梯度变化量)
注意:为了保持收敛性,拉格朗日函数的梯度变化通常使用当前乘子估计 \(\lambda_{k+1}\) 计算。
对于大规模问题,我们通常使用 有限内存拟牛顿法(Limited-memory Quasi-Newton Methods),其中最流行的是 L-BFGS(Limited-memory BFGS)。
L-BFGS如何工作:
- 它不显式地存储完整的 \(n \times n\) 矩阵 \(B_k\)。
- 它只存储最近 \(m\)(例如 \(m=10\))对的 \(\{s_i, y_i\}\) 向量。
- 通过这些向量,可以在需要时“即时”计算出矩阵-向量乘积 \(B_k d\) 或逆矩阵-向量乘积 \(H_k d \approx B_k^{-1} d\),这对于求解QP子问题至关重要。
- 存储代价仅为 \(O(m n)\),计算矩阵-向量乘积的代价也为 \(O(m n)\),远低于 \(O(n^2)\)。
更新过程:
- 在每次迭代获得新的 \(s_k\) 和 \(y_k\) 后,将它们加入存储队列。
- 如果队列已满(超过 \(m\) 对),则丢弃最旧的一对。
- 矩阵 \(B_k\) 本身由这些向量通过递推公式隐式定义。
步骤3:完整的近似Hessian SQP算法步骤
结合上述思想,算法步骤如下:
步骤0:初始化
- 选择初始点 \(x_0\),初始乘子估计 \(\lambda_0\)(可以全零或基于初始约束计算)。
- 选择初始Hessian近似 \(B_0\)(通常取为单位矩阵 \(I\),或通过少量梯度信息初始化)。
- 设置参数:L-BFGS记忆长度 \(m\),线搜索参数(如 \(\alpha_{\min}\), \(\beta, \sigma\) 等),收敛容差 \(\epsilon\)。
步骤1:检查收敛
- 计算当前点的约束违反度 \(\|c(x_k)\|\) 和最优性条件(KKT条件)的残差。
- 如果均小于 \(\epsilon\),则终止,输出 \(x_k\) 作为近似解。
步骤2:构建并求解QP子问题
- 使用L-BFGS公式,利用存储的 \(\{s_i, y_i\}\) 向量,隐式表示当前Hessian近似 \(B_k\)。
- 构建QP子问题:
最小化 \(q_k(d) = \nabla f(x_k)^T d + \frac{1}{2} d^T B_k d\)
满足 \(c_i(x_k) + \nabla c_i(x_k)^T d = 0, \quad i = 1, \ldots, m\)
\(c_i(x_k) + \nabla c_i(x_k)^T d \geq 0, \quad i = m+1, \ldots, m+p\) - 由于 \(B_k\) 是大型矩阵,我们使用 迭代求解器(如共轭梯度法、内点法)来求解此QP,这些求解器只需要矩阵-向量乘积 \(B_k d\),而L-BFGS能高效提供。
- 求解得到搜索方向 \(d_k\) 和相应的乘子估计 \(\lambda_{k+1}\)。
步骤3:执行线搜索(Merit Function)
- 定义价值函数(Merit Function)来衡量进展,例如 \(\phi(x; \mu) = f(x) + \mu \|c(x)\|\),其中 \(\mu\) 是罚参数。
- 沿着方向 \(d_k\) 进行线搜索,找到步长 \(\alpha_k > 0\) 使得:
\(\phi(x_k + \alpha_k d_k; \mu_k) \leq \phi(x_k; \mu_k) + \beta \alpha_k D_d \phi(x_k; \mu_k)\)
其中 \(D_d \phi\) 是价值函数在方向 \(d_k\) 上的方向导数, \(\beta \in (0,1)\) 是线搜索参数。 - 更新决策变量:\(x_{k+1} = x_k + \alpha_k d_k\)。
步骤4:更新Hessian近似(L-BFGS更新)
- 计算 \(s_k = x_{k+1} - x_k\)。
- 计算 \(y_k = \nabla_x L(x_{k+1}, \lambda_{k+1}) - \nabla_x L(x_k, \lambda_{k+1})\)。
- 检查曲率条件:如果 \(s_k^T y_k > 0\),则将 \((s_k, y_k)\) 对加入L-BFGS存储;否则,跳过此次更新(或进行修正,如使用 \(y_k + \delta I s_k\) 确保正定性)。
步骤5:更新罚参数(可选但推荐)
- 根据约束违反度和乘子大小,调整价值函数中的罚参数 \(\mu_k\),以保证价值函数是“精确”的(即其最小值与原问题解一致)。
步骤6:循环
- 设置 \(k = k+1\),返回步骤1。
步骤4:关键参数选择与收敛性保障策略
-
L-BFGS记忆长度 \(m\):
- 通常取 \(5 \leq m \leq 20\)。更大的 \(m\) 能提供更准确的Hessian近似,但计算和存储成本线性增加。
- 对于大规模问题,即使 \(m=10\) 也能在计算效率和近似质量间取得良好平衡。
-
初始Hessian近似 \(B_0\):
- 在L-BFGS中,每次递推计算需要一个初始矩阵 \(B_k^0\)(通常在对角线上缩放的单位矩阵)。
- 常用缩放:\(B_k^0 = \gamma_k I\),其中 \(\gamma_k = \frac{s_{k-1}^T y_{k-1}}{y_{k-1}^T y_{k-1}}\),这有助于保持Hessian近似条件良好。
-
确保正定性:
- SQP子问题需要 \(B_k\) 至少正半定以保证QP是凸的(从而易于求解)。
- L-BFGS在曲率条件 \(s_k^T y_k > 0\) 满足时能保证 \(B_k\) 正定。
- 如果曲率条件不满足,可对 \(y_k\) 进行修正(如 Powell’s damping):\(\hat{y}_k = \theta y_k + (1-\theta) B_k s_k\),其中 \(\theta \in [0,1]\) 使 \(s_k^T \hat{y}_k > 0\)。
-
收敛性保障:
- 全局收敛:通过价值函数线搜索保证每次迭代都减少价值函数,从而收敛到稳定点。
- 超线性收敛:在解附近,如果Hessian近似满足 \(\| (B_k - \nabla_{xx}^2 L(x_*, \lambda_*)) d_k \| / \| d_k \| \to 0\),且步长 \(\alpha_k\) 最终取1,算法可实现超线性收敛。L-BFGS更新在适当条件下能提供这种性质的近似。
- 可行性维持:对于不等式约束,QP子问题的解可能不完全可行。通过价值函数(包含约束违反惩罚)的线搜索,算法能平衡最优性与可行性,最终收敛到可行点。
-
大规模QP求解器:
- 由于 \(B_k\) 没有显式形式,求解QP子问题需要使用仅需要矩阵-向量乘积的迭代求解器。
- 内点法(屏障法)或 有效集法 的变种可以与L-BFGS结合,每次迭代仅计算 \(B_k d\) 而不构造完整矩阵。
- 这要求QP求解器能处理大规模稀疏约束矩阵,通常约束梯度 \(\nabla c_i(x_k)\) 也是稀疏的,可以进一步利用稀疏性节省计算。
总结
通过上述步骤,我们设计了一个 基于近似Hessian的SQP算法,它利用 L-BFGS 技术高效地近似Hessian矩阵,从而能够处理大规模非线性规划问题。算法的核心优势在于:
- 计算高效:避免了精确Hessian的计算和存储。
- 内存友好:存储需求仅为 \(O(m n)\)。
- 收敛可靠:结合价值函数线搜索,保证了全局收敛性,并在解附近达到超线性收敛速率。
这种方法是许多大规模非线性优化软件(如SNOPT、IPOPT的某些模式)的核心组成部分,广泛应用于工程设计、机器学习参数估计等领域。