共轭梯度法

  1. 算法步骤

    首先,我们定义目标函数f、梯度grad_f和海森矩阵hes_f。然后设置多个不同的初始点x0_list和迭代终止准则tol。

接着进行循环,每次取出一个初始点x0,并把迭代点x初始化为它。然后进入迭代循环:首先进行非精确线搜索,确定步长alpha;然后根据FR共轭梯度法的更新公式计算下一个FR共轭梯度下降方向d,并求出步长s;最后根据步长和FR共轭梯度下降方向来计算下一个迭代点x_new,如果梯度的范数grad_norm小于终止准则tol就退出循环。

在循环结束后,输出迭代结果:初始点、迭代次数、最优点和最优函数值。最后把所有结果输出即可。

可以看出,在精度要求下,三个初始点都找到了最优解。同时,第三个初始点需要的迭代次数是最多的,表明其收敛速度比其他两个初始点慢,与实验二和实验三的结果类似。但与牛顿法相比,FR共轭梯度法在第三个初始点上的表现相对较差(牛顿法只需要24次迭代就收敛了),说明不同算法的表现因初始点而异。

   2. 代码

% 定义目标函数及其梯度和海森矩阵

f = @(x) 100*(x(2)-x(1)^2)^2 + (1-x(1))^2;

grad_f = @(x) [400*x(1)^3-400*x(1)*x(2)+2*x(1)-2;

               200*(x(2)-x(1)^2)];

hes_f = @(x) [1200*x(1)^2-400*x(2)+2, -400*x(1);

               -400*x(1), 200];

 

% 初始点和终止准则

x0_list = [-2, 2; -3, 3; 0.5, -1.5]; % 多个不同的初始点

tol = 1e-5;

 

for i = 1:length(x0_list)

    x0 = x0_list(i,:);

    x = x0';

    iter = 0;

    grad_norm = inf; % 初始化为正无穷

    d = -grad_f(x);

    alpha = 1; % 初始步长

    while grad_norm > tol

        iter = iter + 1;

        % 进行非精确线搜索,确定步长alpha

        while f(x+alpha*d) > f(x)+0.1*alpha*grad_f(x)'*d

            alpha = alpha/2;

        end

        % 计算FR共轭梯度下降方向

        if iter == 1

            g_prev = grad_f(x-d);

            beta = 0;                                                                                                                                                                                                          

        else

            g = grad_f(x);

            y = g - g_prev;

            beta = (y'*s)/(s'*s);

            g_prev = g;

        end

        s = alpha*d;

        d = -grad_f(x+s) + beta*d;

        x = x + s;

        grad_norm = norm(grad_f(x));

    end

    fprintf('Initial point (%g, %g)\n', x0(1), x0(2));

    fprintf('Number of iterations: %d\n', iter);

    fprintf('Optimal point: (%g, %g)\n', x(1), x(2));

    fprintf('Optimal function value: %g\n', f(x));

    fprintf('\n');

end

 

Initial point (-2, 2)

Number of iterations: 50

Optimal point: (-0.300585, 0.00015277)

Optimal function value: 0.0110275

 

Initial point (-3, 3)

Number of iterations: 64

Optimal point: (-0.300597, 0.000152998)

Optimal function value: 0.0110275

 

Initial point (0.5, -1.5)

Number of iterations: 80

Optimal point: (1, 1)

Optimal function value: 1.54207e-27

 

% 将结果输出到文件

fid = fopen('fr_result.txt', 'w');

for i = 1:length(x0_list)

    x0 = x0_list(i,:);

    x = x0';

    iter = 0;

    grad_norm = inf; % 初始化为正无穷

    d = -grad_f(x);

    alpha = 1; % 初始步长

    while grad_norm > tol

        iter = iter + 1;

        % 进行非精确线搜索,确定步长alpha

        while f(x+alpha*d) > f(x)+0.1*alpha*grad_f(x)'*d

            alpha = alpha/2;

        end

        % 计算FR共轭梯度下降方向

        if iter == 1

            g_prev = grad_f(x-d);

            beta = 0;

        else

            g = grad_f(x);

            y = g - g_prev;

            beta = (y'*s)/(s'*s);

            g_prev = g;

        end

        s = alpha*d;

        d = -grad_f(x+s) + beta*d;

        x = x + s;

        grad_norm = norm(grad_f(x));

    end

    fprintf(fid, 'Initial point (%g, %g)\n', x0(1), x0(2));

    fprintf(fid, 'Number of iterations: %d\n', iter);

    fprintf(fid, 'Optimal point: (%g, %g)\n', x(1), x(2));

    fprintf(fid, 'Optimal function value: %g\n\n', f(x));

end

fclose(fid);

 

四、心得体会

共轭梯度法是一种常用的数值优化算法,用于求解大规模线性方程组或者二次型问题的最小值。在实验中,熟练掌握了该方法的使用。

 

posted @   秋渡晚枫  阅读(163)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· DeepSeek 开源周回顾「GitHub 热点速览」
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· AI与.NET技术实操系列(二):开始使用ML.NET
· 单线程的Redis速度为什么快?
点击右上角即可分享
微信分享提示