基于MATLAB的BFGS拟牛顿法最优化算法实现
项目简介
本项目实现了一套完整的BFGS(Broyden-Fletcher-Goldfarb-Shanno)拟牛顿法算法,用于解决无约束的非线性最优化问题。项目使用MATLAB语言开发,旨在通过迭代方式寻找目标函数的极小值点。该算法的核心优势在于它不需要计算二阶海森矩阵(Hessian Matrix)及其逆矩阵,而是通过梯度信息的历史迭代来近似海森矩阵的逆,从而在保证收敛速度的同时大幅降低计算复杂度。本项目特别针对经典的非凸病态函数——Rosenbrock函数进行了测试和演示,并提供了完善的可视化分析工具。
功能特性
- BFGS 拟牛顿法核心算法:实现了基于逆海森矩阵近似更新的标准BFGS算法,支持高效求解多元函数极值。
- 灵活的线搜索策略:内置了两种步长选择策略,确保全局收敛性:
*
Wolfe-Powell 准则(默认):同时满足充分下降条件和曲率条件,稳健性更强。
*
Armijo 准则:基于回溯法的非精确线搜索,满足充分下降条件。
* 支持解析梯度(Analytical Gradient):如果用户提供了梯度的数学表达式,算法将优先使用以获得最高精度。
* 支持数值梯度(Numerical Gradient):如果未提供梯度函数,算法自动使用中心差分法进行数值近似,增强了通用性。
- 鲁棒的收敛控制:通过梯度模长容差(Tolerance)和最大迭代次数双重标准来控制算法终止,防止死循环。
- 结果可视化:提供双视图可视化分析,包括优化路径等高线图(对数标度)和收敛曲线(目标函数值与梯度模长),直观展示算法性能。
系统要求
- MATLAB R2016a 或更高版本(代码主要依赖基础数学运算和绘图功能,无特殊工具箱依赖)。
使用方法
本项仅包含一个主程序脚本,直接运行即可执行优化过程。代码结构设计为“设置-求解-分析”的一体化流程:
- 定义问题:在脚本开头的参数设置区域,可以修改目标函数句柄
objFunc 和其梯度句柄 gradFunc。默认配置为求解二维 Rosenbrock 函数。 - 调整参数:通过修改
x0(初始点)、options.Tol(收敛容差)、options.MaxIter(最大迭代限制)和 options.LineSearch(线搜索方法)来控制算法行为。 - 运行求解:运行脚本后,MATLAB 命令窗口将实时输出迭代过程中的关键信息(迭代步数、函数值、梯度模长、步长)。
- 查看分析:计算完成后,脚本将输出最终的最优解、函数最小值,并弹出一个图形窗口展示可视化的优化路径和收敛趋势。
代码实现逻辑与算法细节
本项目的主程序脚本集成了参数定义、核心算法逻辑、辅助计算函数以及可视化模块,具体实现细节如下:
1. 问题定义与初始化
程序首先定义了优化目标——Rosenbrock函数,这是一个典型的非凸函数,其全局最小值位于 (1,1)。程序同时配置了初始猜测点(默认 [-1.2; 1.0])以及算法的控制参数(容差 1e-6,最大迭代 1000 次)。这里采用了函数句柄的方式定义目标函数,使得替换其他多元函数变得非常便捷。
2. BFGS 核心求解器
bfgs_solver 函数是整个项目的核心。
- 初始化:算法初始化逆海森矩阵近似矩阵 $H$ 为单位矩阵 $I$。
- 迭代循环:
1.
计算梯度:根据当前点计算梯度 $g_k$。
2.
收敛判断:检查当前梯度的模长是否小于设定的容差,若是则判定收敛并退出。
3.
确定搜索方向:利用拟牛顿公式 $d_k = -H_k cdot g_k$ 计算下降方向。
4.
线搜索:调用线搜索子函数寻找最佳步长 $alpha_k$。
5.
更新位置:计算新点 $x_{k+1} = x_k + alpha_k d_k$。
6.
更新矩阵 $H$:计算位置差量 $s_k = x_{k+1} - x_k$ 和梯度差量 $y_k = g_{k+1} - g_k$。在满足曲率条件($s_k^T y_k > 0$)的前提下,利用 Sherman-Morrison 公式更新逆海森矩阵近似 $H_{k+1}$,确保其正定性。
3. 线搜索策略实现
代码实现了两种非精确线搜索机制来确定步长:
- Wolfe 准则 (
line_search_wolfe):通过迭代寻找满足“Armijo 充分下降条件”和“曲率条件”的步长。该函数实现了区间搜索逻辑,当步长过大时不满足下降条件则缩小区间,当步长过小导致斜率下降不足时则扩大区间。这是 BFGS 推荐的策略,因为它能更好地保持矩阵 $H$ 的正定性。 - Armijo 准则 (
line_search_armijo):作为一个更简单的备选方案,该函数从初始步长开始,通过不断乘以衰减系数(如0.5)进行回溯,直到找到满足函数值充分下降的点。
4. 数值梯度计算
finite_difference_grad 函数提供了一种后备机制。当用户未提供解析梯度函数句柄时,该函数使用中心差分公式
(f(x+h) - f(x-h)) / 2h 来近似计算每一点的梯度向量,保证了算法在无法通过数学推导获得梯度时的可用性。
5. 可视化分析
visualize_results 函数负责生成直观的分析图表:
- 优化路径图:使用
meshgrid 生成网格数据,绘制目标函数的等高线图。为了更清晰地展示 Rosenbrock 函数平坦谷底的细节,等高线采用了 log10 对数标度进行着色。红色的连线清晰地展示了从起点到最优解的搜索轨迹。 - 收敛曲线图:利用双y轴(
yyaxis)同时绘制了“目标函数值”和“梯度模长”随迭代次数变化的曲线。两条曲线均采用半对数坐标(semilogy),便于观察误差随迭代次数呈超线性收敛的特征。