共轭梯度法
最速下降法以及牛顿法都具有其自身的局限性。本文将要介绍的共轭梯度法是介于最速下降法与牛顿法之间的一种无约束优化算法,它具有超线性的收敛速度,而且算法结构简单,容易编程实现。此外,根最速下降法相类似,共轭梯度法只用到了目标函数及其梯度值,避免了二阶导数的计算,从而降低了计算量和存储量,因此它是求解无约束优化问题的一种比较有效而使用的算法。
一、共轭方向发
共轭方向法的基本思想是在求解维正定二次目标函数极小点时产生一组共轭方向作为搜索方向,在线搜索条件下算法之多迭代步即能求得极小点。京故宫适当修正后共轭方向法可以推广到求解一般非二次目标函数情形。下面先介绍共轭方向的概念。
定义1:设是阶对称正定矩阵,若维向量组,则乘是共轭的。
显然,向量组的共轭是正交的推广,即当(单位阵)时,上述定义变成了向量组正交的定义。此外,不难证明,对称正定矩阵的共轭向量组必然是线性无关的。
下面我们考虑求解正定二次目标函数极小点的共轭方向法。设
其中是阶对称正定阵,为为常向量,为常数。我们有下面的算法:
算法1:共轭方向法
0. 给定迭代精度和初始点。计算。选取初始方向使得。令.
- 若,停算,输出.
- 利用线搜索方法确定步长
- 令,并计算.
- 选取满足下降性和共轭性条件:.
- 令,转步1
该算法的收敛性证明略过,如果感兴趣,可以去查找相应的数值优化专著。这里直接给出结论,在精确线搜索下,算法1求解正定二次目标函数极小化问题,之多在步内即可求得其唯一极小点。这种能在有限步内求得二次函数极小点的性质通常称为二次终止性。
二、共轭梯度法
共轭梯度法是在每一步迭代利用当前点处的最速下降方向来生成关于凸二次函数的海塞阵的共轭方向,并建立求在上的极小点的方法。这一方法最早是由Hesteness和Stiefel于1952年为求解正定线性方程组而提出来的,后经Fletcher等人研究并应用于无约束优化问题取得了丰富的成果,共轭梯度法也因此成为当前求解无约束优化问题的重要算法类。
设函数如(1)式所定义,则的梯度和海塞矩阵为
下面我们讨论算法(1)中共轭方向的构造。我们取初始方向为初始点处的负梯度方向,即
从出发沿方向进行线搜索得到步长,令
其中满足条件
在处,用在的负梯度方向与的组合来生成,即
然后选取系数使与关于G共轭,即令
来确定,将(6)代入(5)得
由(2)得
故由(3)~(5)可得
现假设已得到互相共轭得搜索方向,精确线搜索得到得步长为,且满足
现令
其中得选择要满足
用左乘(10)得
类似于(8),我们有
及
于是由归纳法假设(9)可得
于是,第k步得搜索方向为
其中由(12)确定,即
同时有。这样确定了一组由负梯度方向形成得共轭方向,而把沿着这组方向进行迭代得方向称为共轭梯度法。其证明过程这里略过。
下面我们给出共轭梯度法求解无约束优化问题(1)极小点得算法步骤
算法2:共轭梯度法
0. 给定迭代精度和初始点。计算。令
- 若,停算,输出
- 计算搜索方向:
KaTeX parse error: Unknown column alignment: s at position 29: …\begin{array}{ls̲c} -g_k,&k=0,\\…
其中当时,由(15)确定 - 利用线搜索方法确定搜索步长
- 令,并计算
- 令,转步1
计算公式(15)是由Fletcher和Reeves给出得,故称之为FR公式,算法2也称之为FR共轭梯度法。除FR工诗外,尚有下列著名公式:
三、共轭梯度法得matlab实现
在共轭梯度法得实际使用中,通常在迭代n步或n+1步之后,重新选取负梯度方向作为搜索方向,我们称之为再开始共轭梯度法。这是因为对于一般非二次函数而言,n步迭代后共轭梯度法产生得搜索方向往往不再具有共轭性。而对于大规模问题,常常每步就进行再开始。此外,当搜索方向不是下降方向时,也插入负梯度方向所作为搜索方向。
这里给出基于Armijo-rule非精确线搜索得再开始FR共轭梯度法得matlab程序。
function [fmin, xmin] = frcg(fun, gfun, x0, epsilon)
maxk = 5000;
rho = 0.6;
sigma = 0.4;
k = 0;
n = length(x0);
while k < maxk
g = feval(gfun, x0);
itern = k - (n+1) * floor(k / (n + 1));
itern = itern + 1;
if (itern == 1)
d = -g;
else
beta = (g' * g) / (g0' * g0);
d = -g + beta * d0; gd = g' * d;
if (gd >= 0.0)
d = -g;
end
end
if (norm(g) < epsilon), break; end
m = 0; mk = 0;
while (m < 20) % armijo-rule
if (feval(fun, x0 + rho^m*d) < feval(fun, x0) + sigma * rho^m*g'*d)
mk = m; break;
end
m = m + 1;
end
x0 = x0 + rho^mk*d;
val = feval(fun, x0);
fprintf('kIter = %d, fmin = %f\n', k, val);
g0 = g; d0 = d;
k = k+1;
end
x = x0;
val = feval(fun, x);
xmin = x;
fmin = val;
end
利用程序求解无约束优化问题
该问题由精确解
求解main函数
x0 = [0, 0]';
epsilon = 1e-4;
[fmin, xmin] = frcg('func', 'gfunc', x0, epsilon);
fprintf('frcg: fmin = %f, xmin = (%f, %f)\n', fmin, xmin(1), xmin(2));
[x, f] = fminsearch('func', x0);
fprintf('build-in search: fmin = %f, xmin = (%f, %f)\n', f, x(1), x(2));
函数定义以及梯度求解
function f = func(x)
f = 100 * (x(1)^2 - x(2))^2 + (x(1) - 1)^2;
end
function grad = gfunc(x)
grad = [400 * x(1) * (x(1)^2-x(2))+2*(x(1)-1); ...
-200 * (x(1)^2-x(2))];
end
求解结果为:
frcg: fmin = 0.000000, xmin = (0.999921, 0.999841)
build-in search: fmin = 0.000000, xmin = (1.000004, 1.000011)