共轭梯度原理
- 资料网站:原理:https://blog.csdn.net/chunyun0716/article/details/53730127
- 举例:
,求它的最小值。共轭梯度可以求解一个二次型函数的最小值。
结果: 迭代了1次
原理概述:共轭梯度法不需要预先给定Q共轭方向,而是随着迭代的进行不断产生Q共轭方向。在每次的迭代中,利用上一个搜索方向和目标函数在当前迭代点的梯度向量 之间的线性组合构造一个新的方向,使其与前边已经产生的搜索方向组成Q共轭方向。对于一个n维二次型函数,沿着Q共轭方向进行搜索,经过n次迭代,即可得到极小点。
3. 算法细节
syms x1 x2;
f = (x1-2)^2+(x2-4)^2;
x = [x1 x2];
x0 = [0 0 ];
tol = 0.1;
[fmin xmin count] = myCG_func(f, x, x0, tol);
function [fmin xmin count] = myCG_func(f, x, x0, tol)
%% 函数说明:fmin为求得的最小值,xmin为取得最小值时的变量值,count为迭代次数。
n = length(x);
nf = cell(1,n);%行cell,每个cell为f对每个变量x的微分
for i = 1:n%对每个变量求微分
nf{i} = diff(f, x(i));%nf(x1),nf(x2)
end
%nablaf(x0)
nfv = subs(nf, x, x0);
nfv_pre = nfv;
xv = x0;
d = - nfv;%d0=-nablaf(x0)
syms lambdas;
count = 0;
k = 0;
while norm(nfv) > tol
xv = xv + lambdas*d;%新的x
%由于d已得,需最优化求lambda,即nablaf(xk)d0 = 0
phi = subs(f, x, xv);
nphi = diff(phi);
lambda = solve(nphi);%求得最优值lambda
lambda = double(lambda);
if lambda < 1e-5
break;
end
%为下一次迭代做准备
% dk的更新法则
%d = -nablaf(x_k+1) + alpha_k * d_k
% xv = double(xv);%新的x, x_k+1
xv = subs(xv, lambdas, lambda);
nfv = subs(nf, x, xv);
alpha = sumsqr(nfv)/sumsqr(nfv_pre);
d = -nfv + alpha*d;
nfv_pre = nfv;
count = count + 1;%迭代次数
k = k + 1;
if k>=n
k=0;
d = -nfv;
end
end
fmin = double(subs(f, x, xv));
xmin = double(xv);
end