采用Armjio非精确线搜索求步长的FR非线性共轭梯度法--MATLAB实现
作者:互联网
文章目录
前言
多元函数的求解使我们生活中常见的一些问题的缩影,对于多元函数极小点的解法,我们可以利用最优化中的相关算法来求解,本文采用 MATLAB 程序,利用 FR 非线性共轭梯度算法求解 Rosenbrock 函数的极小点。
一、数学原理
可参考此文章:最速下降法/steepest descent,牛顿法/newton,共轭方向法/conjugate direction,共轭梯度法/conjugate gradient 及其他
算法伪码如下:
二、代码实现
1.Armjio非精确线搜索求步长
详情可参考我的另一篇博客:采用非精确线搜索求步长的Armjio准则–MATLAB实现
function [alpha] = Armjio(fun, grid, x0, dk)
%
% Function [alpha, xk, fx, k] = Armjio(fun, grid, x0, dk)
% 求出函数fun在x0处以dk为下降方向时的步长alpha,同时返回相对应的下
% 一个下降点xk以及xk处的函数值fx,k为迭代次数
% -----------------------------------------------------------
% 输入:
% fun 函数名称(字符变量)
% grid 梯度函数名称(字符变量)
% x0 迭代点(列向量)
% dk 函数在迭代点处的下降方向(列向量)
%
% 输出:
% alpha 函数在x0处以dk为下降方向时的下降步长
% xk 函数在x0处以dk为下降方向,以alpha为步长
% 求得的下降点
% fx 函数在下降点xk处的函数值
% k 求步长算法迭代次数
% -----------------------------------------------------------
% by Zhi Qiangfeng
%
beta = 0.333; % 步长 alpha 的迭代系数,小于 1
rho = 1e-3; % 泰勒展开式补足系数,0 < rho < 1/2
alpha = 1; % 初始步长为 1
k = 0; % 统计迭代次数
gk = feval(grid, x0); % x0处的梯度值
fd = feval(fun, x0 + alpha * dk); % 函数在下一个迭代点处的目标函数值
fk = feval(fun, x0) + alpha * rho * gk' * dk; % 函数在下一个迭代点处的泰勒展开值
while fd > fk
alpha = beta * alpha;
fd = feval(fun, x0 + alpha * dk);
fk = feval(fun, x0) + alpha * rho * gk' * dk;
k = k + 1;
end
end
2.FR共轭梯度法
代码如下:
function [f, xk, k] = FRConjudate(x0, fun, grid, eps, kmax)
%
% function [f, xk, k] = FRConjudate(x0, fun, grid, eps, kmax)
% 求出函数fun从初始点x0处以共轭梯度法计算下降方向,
% 采用 Armjio 准则计算迭代步长,求出函数的极小点
% -----------------------------------------------------------
% 输入:
% x0 初始点(列向量)
% fun 函数文件名称(字符变量)
% grid 梯度函数文件名称(字符变量)
% eps 函数在迭代点处的下降方向(列向量)
% kmax 函数的最大迭代次数
%
% 输出:
% f 函数在极小值 xk 处的目标函数值
% xk 函数采用此方法求得的极小点
% k 求极小点算法迭代次数
% -----------------------------------------------------------
% by Zhi Qiangfeng
%
k = 0;
n = length(x0); % n 为未知数个数
xk = x0;
gk = feval(grid, xk);
dk = -gk; % 初始下降方向选为负梯度方向
while k <= kmax
if norm(gk) < eps
break
end
gk_ = gk; % gk_ 保存上一个点的梯度值
gk = feval(grid, xk);
dk_ = dk; % dk_ 保存上一个下降方向
if mod(k, n) == 0
dk = -gk; % 每 n 步重新调整下降方向
else
beta = (gk' * gk) / (gk_' * gk_); % FR公式
dk = -gk + beta * dk_; % 更新下降方向
if gk' * dk >= 0
dk = -gk; % 非精确线搜索无法保证迭代方向下降性
end
end
alpha = Armjio(fun, grid, xk, dk);
xk = xk + alpha * dk;
k = k + 1;
end
f = feval(fun, xk);
end
此处不列出输出结果以及调用方法,调用方式以及方法可参考这篇博客:采用Armjio准则求步长的BFGS/DFP拟牛顿方法–MATLAB实现
附录
最优化相关算法设计数学原理:最优化/Optimization文章合集
最优化相关MATLAB实现程序:Z.Q.Feng的最优化笔记
有帮助可以点赞哦,谢谢大家的支持~
标签:xk,FR,函数,--,步长,fun,alpha,x0,dk 来源: https://blog.csdn.net/weixin_46584887/article/details/117738066