共轭梯度法

本文介绍了共轭梯度法,一种介于最速下降与牛顿法之间的无约束优化算法,它以超线性收敛速度、简单结构和低计算需求著称。通过共轭方向的构造,算法在二次目标函数极小化中展现高效性,还涵盖Matlab实现与实例演示。

共轭梯度法

最速下降法以及牛顿法都具有其自身的局限性。本文将要介绍的共轭梯度法是介于最速下降法与牛顿法之间的一种无约束优化算法,它具有超线性的收敛速度,而且算法结构简单,容易编程实现。此外,根最速下降法相类似,共轭梯度法只用到了目标函数及其梯度值,避免了二阶导数的计算,从而降低了计算量和存储量,因此它是求解无约束优化问题的一种比较有效而使用的算法。

一、共轭方向发
共轭方向法的基本思想是在求解nnn维正定二次目标函数极小点时产生一组共轭方向作为搜索方向,在线搜索条件下算法之多迭代nnn步即能求得极小点。京故宫适当修正后共轭方向法可以推广到求解一般非二次目标函数情形。下面先介绍共轭方向的概念。
定义1:设GGGnnn阶对称正定矩阵,若nnn维向量组d1,d2,⋯ ,dm(m≤n)满足d_1,d_2,\cdots,d_m(m\le n)满足d1,d2,,dm(mn)满足diTGdj=0,i≠jd_i^TGd_j=0,i\neq jdiTGdj=0,i=j,则乘d1,d2,⋯ ,dmd_1,d_2,\cdots,d_md1,d2,,dmGGG共轭的。
显然,向量组的共轭是正交的推广,即当G=IG=IG=I(单位阵)时,上述定义变成了向量组正交的定义。此外,不难证明,对称正定矩阵GGG的共轭向量组必然是线性无关的。
下面我们考虑求解正定二次目标函数极小点的共轭方向法。设
min⁡f(x)=12xTGx+bTx+c(1) \min f(x)=\frac{1}{2}x^TGx+b^Tx+c\tag{1} minf(x)=21xTGx+bTx+c(1)
其中GGGnnn阶对称正定阵,bbbnnn为常向量,ccc为常数。我们有下面的算法:


算法1:共轭方向法
0. 给定迭代精度0≤ϵ≤10\le\epsilon\le 10ϵ1和初始点x0x_0x0。计算g0=∇f(x0)g_0=\nabla f(x_0)g0=f(x0)。选取初始方向d0d_0d0使得d0Tg0<0d_0^Tg_0\lt 0d0Tg0<0。令k=0k=0k=0.

  1. ∣∣gk∣∣≤ϵ||g_k||\le\epsilon∣∣gk∣∣ϵ,停算,输出x∗≈xkx^*\approx x_kxxk.
  2. 利用线搜索方法确定步长αk\alpha_kαk
  3. xk+1=xk+αkdkx_{k+1}=x_k+\alpha_kd_kxk+1=xk+αkdk,并计算gk+1=∇f(xk+1)g_{k+1}=\nabla f(x_{k+1})gk+1=f(xk+1).
  4. 选取dk+1d_{k+1}dk+1满足下降性和共轭性条件:dk+1Tgk+1<0,dk+1TGdi=0,,i=0,1,⋯ ,kd_{k+1}^Tg_{k+1}\lt 0,d_{k+1}^TGd_i=0,\quad,i=0,1,\cdots,kdk+1Tgk+1<0,dk+1TGdi=0,,i=0,1,,k.
  5. k=k+1k=k+1k=k+1,转步1

该算法的收敛性证明略过,如果感兴趣,可以去查找相应的数值优化专著。这里直接给出结论,在精确线搜索下,算法1求解正定二次目标函数极小化问题,之多在nnn步内即可求得其唯一极小点。这种能在有限步内求得二次函数极小点的性质通常称为二次终止性。

二、共轭梯度法
共轭梯度法是在每一步迭代利用当前点处的最速下降方向来生成关于凸二次函数fff的海塞阵GGG的共轭方向,并建立求fffRn\mathbb{R^n}Rn上的极小点的方法。这一方法最早是由Hesteness和Stiefel于1952年为求解正定线性方程组而提出来的,后经Fletcher等人研究并应用于无约束优化问题取得了丰富的成果,共轭梯度法也因此成为当前求解无约束优化问题的重要算法类。
设函数如(1)式所定义,则fff的梯度和海塞矩阵为
g(x)=∇f(x)=Gx+b,G(x)=∇2f(x)=G(2) g(x)=\nabla f(x)=Gx+b,\quad G(x)=\nabla^2 f(x)=G\tag{2} g(x)=f(x)=Gx+b,G(x)=2f(x)=G(2)
下面我们讨论算法(1)中共轭方向的构造。我们取初始方向d0d_0d0为初始点x0x_0x0处的负梯度方向,即
d0=−∇f(x0)=−g0(3) d_0=-\nabla f(x_0)=-g_0 \tag{3} d0=f(x0)=g0(3)
x0x_0x0出发沿d0d_0d0方向进行线搜索得到步长α0\alpha_0α0,令
x1=x0+α0d0 x_1=x_0+\alpha_0d_0 x1=x0+α0d0
其中α0\alpha_0α0满足条件
∇f(x1)Td0=g1Td0(4) \nabla f(x_1)^Td_0=g_1^Td_0 \tag{4} f(x1)Td0=g1Td0(4)
x1x_1x1处,用fffx1x_1x1的负梯度方向−g1-g_1g1d0d_0d0的组合来生成d1d_1d1,即
d1=−g1+β0d0(5) d_1=-g_1+\beta_0d_0 \tag{5} d1=g1+β0d0(5)
然后选取系数β0\beta_0β0使d1d_1d1d0d_0d0关于G共轭,即令
d1TGd0=0(6) d_1^TGd_0 = 0 \tag{6} d1TGd0=0(6)
来确定β0\beta_0β0,将(6)代入(5)得
β0=g1TGd0d0TGd0(7) \beta_0 = \frac{g_1^TGd_0}{d_0^TGd_0} \tag{7} β0=d0TGd0g1TGd0(7)
由(2)得
g1−g0=G(x1−x0)=α0Gd0(8) g_1-g_0=G(x_1-x_0)=\alpha_0Gd_0 \tag{8} g1g0=G(x1x0)=α0Gd0(8)
故由(3)~(5)可得
g2Tg0=0,g2Tg1=0,d0Tg0=−g0Tg0,d1Tg1=−g1Tg1 g_2^Tg_0=0,g_2^Tg_1=0,d_0^Tg_0=-g_0^Tg_0,d_1^Tg_1=-g_1^Tg_1 g2Tg0=0,g2Tg1=0,d0Tg0=g0Tg0,d1Tg1=g1Tg1
现假设已得到互相共轭得搜索方向d1,d2,⋯ ,dk−1d_1,d_2,\cdots,d_{k-1}d1,d2,,dk1,精确线搜索得到得步长为α0,α1,⋯ ,αk−1\alpha_0,\alpha_1,\cdots,\alpha_{k-1}α0,α1,,αk1,且满足
{dk−1TGdi=0,i=0,1,⋯ ,k−2,diTgi=−giTgi,i=0,1,⋯ ,k−1,gkTgi=0,gkTdi=0,i=0,1,⋯ ,k−1.(9) \left\{ \begin{array}{rcl} d_{k-1}^TGd_i=0, &i=0,1,\cdots,k-2,\\ d_i^Tg_i=-g_i^Tg_i,&i=0,1,\cdots,k-1,\\ g_k^Tg_i=0,g_k^Td_i=0,&i=0,1,\cdots,k-1. \end{array} \right. \tag{9} dk1TGdi=0,diTgi=giTgi,gkTgi=0,gkTdi=0,i=0,1,,k2,i=0,1,,k1,i=0,1,,k1.(9)
现令
dk=−gk+βk−1dk−1+∑i=0k−1βk(i)di(10) d_k=-g_k+\beta_{k-1}d_{k-1}+\sum_{i=0}^{k-1}\beta_{k}^{(i)}d_i\tag{10} dk=gk+βk1dk1+i=0k1βk(i)di(10)
其中βk−1,βk(i)(i=0,1,⋯ ,k−2)\beta_{k-1},\beta_k^{(i)}(i=0,1,\cdots,k-2)βk1,βk(i)(i=0,1,,k2)得选择要满足
dkTGdi=0,i=0,1,⋯ ,k−1(11) d_k^TGd_i=0,i=0,1,\cdots,k-1\tag{11} dkTGdi=0,i=0,1,,k1(11)
diTG(i=0,1,⋯ ,k−1)d_i^TG(i=0,1,\cdots,k-1)diTG(i=0,1,,k1)左乘(10)得
βk−1=gkTGdk−1dk−1TGdk−1,βk(1)=gkTGdidiTGdi,i=0,1,⋯ ,k−2(12) \beta_{k-1}=\frac{g_k^TGd_{k-1}}{d_{k-1}^TGd_{k-1}},\beta_k^{(1)}=\frac{g_k^TGd_i}{d_i^TGd_i},i=0,1,\cdots,k-2\tag{12} βk1=dk1TGdk1gkTGdk1,βk(1)=diTGdigkTGdi,i=0,1,,k2(12)
类似于(8),我们有
gi+1−gi=G(xi+1−xi)=αiGdi,i=0,1,⋯ ,k−1 g_{i+1}-g_i=G(x_{i+1}-x_i)=\alpha_iGd_i,i=0,1,\cdots,k-1 gi+1gi=G(xi+1xi)=αiGdi,i=0,1,,k1

αiGdi=gi+1−gi,i=0,1,⋯ ,k−1(13) \alpha_iGd_i=g_{i+1}-g_i,i=0,1,\cdots,k-1\tag{13} αiGdi=gi+1gi,i=0,1,,k1(13)
于是由归纳法假设(9)可得
βk(i)=gkTGdidiTGdi=gkT(gi+1−gi)diT(gi+1−gi)=0,i=0,1,⋯ ,k−2. \beta_k^{(i)}=\frac{g_k^TGd_i}{d_i^TGd_i}=\frac{g_k^T(g_{i+1}-g_i)}{d_i^T(g_{i+1}-g_i)}=0,i=0,1,\cdots,k-2. βk(i)=diTGdigkTGdi=diT(gi+1gi)gkT(gi+1gi)=0,i=0,1,,k2.
于是,第k步得搜索方向为
dk=−gk+βk−1dk−1,(14) d_k=-g_k+\beta_{k-1}d_{k-1},\tag{14} dk=gk+βk1dk1,(14)
其中βk−1\beta_{k-1}βk1由(12)确定,即
βk−1=gkTGdk−1dk−1TGdk−1(15) \beta_{k-1}=\frac{g_k^TGd_{k-1}}{d_{k-1}^TGd_{k-1}}\tag{15} βk1=dk1TGdk1gkTGdk1(15)
同时有dkTgk=−gkTgkd_k^Tg_k=-g_k^Tg_kdkTgk=gkTgk。这样确定了一组由负梯度方向形成得共轭方向,而把沿着这组方向进行迭代得方向称为共轭梯度法。其证明过程这里略过。
下面我们给出共轭梯度法求解无约束优化问题(1)极小点得算法步骤


算法2:共轭梯度法
0. 给定迭代精度0≤ϵ<10\le\epsilon\lt 10ϵ<1和初始点x0x_0x0。计算g0=∇f(x0)g_0=\nabla f(x_0)g0=f(x0)。令k=0k=0k=0

  1. ∣∣gk∣∣≤ϵ||g_k||\le\epsilon∣∣gk∣∣ϵ,停算,输出x)≈xkx^)\approx x_kx)xk
  2. 计算搜索方向dkd_kdk:
    KaTeX parse error: Unknown column alignment: s at position 29: …\begin{array}{ls̲c} -g_k,&k=0,\\…
    其中当k≥1k\ge 1k1时,βk−1\beta_{k-1}βk1由(15)确定
  3. 利用线搜索方法确定搜索步长αk\alpha_kαk
  4. xk+1=xk+αkdkx_{k+1}=x_k+\alpha_kd_kxk+1=xk+αkdk,并计算gk+1=∇f(xk+1)g_{k+1}=\nabla f(x_{k+1})gk+1=f(xk+1)
  5. k=k+1k=k+1k=k+1,转步1

计算公式(15)是由Fletcher和Reeves给出得,故称之为FR公式,算法2也称之为FR共轭梯度法。除FR工诗外,尚有下列著名公式:
βk=gk+1Tgk+1−dkTgk,(Dixon公式)βk=gk+1Tgk+1dkT(gk+1−gk),(Dai−Yuan公式)βk=gk+1T(gk+1−gk)dkT(gk+1−gk),(Crowder−Wolfe公式)βk=gk+1T(gk+1−gk)gkTgk,(Polak,Ribiere,Ployak,PRP公式) \begin{aligned} \beta_k&=\frac{g_{k+1}^Tg_{k+1}}{-d_k^Tg_k}, (Dixon公式) \\ \beta_k&=\frac{g_{k+1}^Tg_{k+1}}{d_k^T(g_{k+1}-g_k)}, (Dai-Yuan公式) \\ \beta_k&=\frac{g_{k+1}^T(g_{k+1}-g_k)}{d_k^T(g_{k+1}-g_k)}, (Crowder-Wolfe公式) \\ \beta_k&=\frac{g_{k+1}^T(g_{k+1}-g_k)}{g_k^Tg_k}, (Polak,Ribiere,Ployak,PRP公式) \\ \end{aligned} βkβkβkβk=dkTgkgk+1Tgk+1,(Dixon公式)=dkT(gk+1gk)gk+1Tgk+1,(DaiYuan公式)=dkT(gk+1gk)gk+1T(gk+1gk),(CrowderWolfe公式)=gkTgkgk+1T(gk+1gk),(Polak,Ribiere,Ployak,PRP公式)

三、共轭梯度法得matlab实现
在共轭梯度法得实际使用中,通常在迭代n步或n+1步之后,重新选取负梯度方向作为搜索方向,我们称之为再开始共轭梯度法。这是因为对于一般非二次函数而言,n步迭代后共轭梯度法产生得搜索方向往往不再具有共轭性。而对于大规模问题,常常每m(m<n或m≪n)m (m<n或m\ll n)m(m<nmn)步就进行再开始。此外,当搜索方向不是下降方向时,也插入负梯度方向所作为搜索方向。
这里给出基于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

利用程序求解无约束优化问题
min⁡x∈R2f(x)=100(x12−x2)2+(x1−1)2 \min_{x\in\mathbb{R^2}}\quad f(x)=100(x_1^2-x_2)^2+(x_1-1)^2 xR2minf(x)=100(x12x2)2+(x11)2
该问题由精确解x∗=(1,1)T,f(x∗)=0x^*=(1,1)^T,f(x^*)=0x=(1,1)T,f(x)=0

求解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)

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值