5.21打卡

工程数学共轭梯度法
• 所花时间:5
• 代码行数:163
• 博客容量:1
• 代码如下:

实验四:共轭梯度法程序设计
一、实验目的
掌握共轭梯度法的基本思想及其迭代步骤;学会运用MATLAB编程实现常用优化算法;能够正确处理实验数据和分析实验结果及调试程序。
二、实验内容
•  编写MATLAB代码实现FR共轭梯度法,求解给定的无约束优化问题。
•  选取几个与实验二(最速下降法)和实验三(牛顿法)中相同的初始点,并给出相关实验结果的对比及分析。
•  撰写实验报告,总结实验结果和心得体会。
三、算法步骤、代码、及结果
•  定义目标函数及其梯度:
 
 
•  初始化:
•	选择初始点。
•	设定终止准则和最大迭代次数。
•  共轭梯度法迭代:
•	计算初始梯度和方向。
•	通过线搜索确定步长。
•	更新变量。
•	计算新的梯度和方向。
•	检查收敛条件。

2. 代码
function conj_gradient()
    % 定义目标函数
    f = @(x) (x(1) + 10*x(2))^2 + 5*(x(3) - x(4))^2 + (x(2) - 2*x(3))^4 + 10*(x(1) - x(4))^4;
    
    % 定义目标函数的梯度
    grad_f = @(x) [
        2*(x(1) + 10*x(2)) + 40*(x(1) - x(4))^3;
        20*(x(1) + 10*x(2)) + 4*(x(2) - 2*x(3))^3;
        10*(x(3) - x(4)) - 8*(x(2) - 2*x(3))^3;
        -10*(x(3) - x(4)) - 40*(x(1) - x(4))^3
    ];
    
    % 初始点集合
    initial_points = [
        0, 0, 0, 0;
        1, 1, 1, 1;
        -1, -1, -1, -1;
        2, 2, 2, 2;
        -2, -2, -2, -2
    ];
    
    % 终止准则
    tol = 1e-6;
    
    % 最大迭代次数
    max_iter = 10000;
    
    % 遍历初始点
    for i = 1:size(initial_points, 1)
        x0 = initial_points(i, :)';
        [x_opt, f_val, iter, f_values] = fletcher_reeves(f, grad_f, x0, tol, max_iter);
        fprintf('初始点: [%f, %f, %f, %f]\n', x0);
        fprintf('迭代次数: %d\n', iter);
        fprintf('最优函数值: %f\n', f_val);
        fprintf('最优点: [%f, %f, %f, %f]\n\n', x_opt);
        
        % 绘制最优值随迭代次数变化的曲线图
        figure;
        plot(1:iter, f_values, '-o');
        title(sprintf('初始点 [%f, %f, %f, %f]', x0));
        xlabel('迭代次数');
        ylabel('函数值');
        grid on;
    end
end

function [x_opt, f_val, iter, f_values] = fletcher_reeves(f, grad_f, x0, tol, max_iter)
    x = x0;
    f_values = zeros(max_iter, 1);
    grad = grad_f(x);
    d = -grad;
    for iter = 1:max_iter
        f_values(iter) = f(x);
        if norm(grad) < tol
            break;
        end
        alpha = line_search(f, grad_f, x, d);
        x = x + alpha * d;
        grad_new = grad_f(x);
        beta = (grad_new' * grad_new) / (grad' * grad);
        d = -grad_new + beta * d;
        grad = grad_new;
    end
    x_opt = x;
    f_val = f(x_opt);
    f_values = f_values(1:iter);
end

function alpha = line_search(f, grad_f, x, d)
    alpha = 1;
    c = 1e-4;
    rho = 0.9;
    while f(x + alpha * d) > f(x) + c * alpha * (grad_f(x)' * d)
        alpha = rho * alpha;
    end
end
3. 结果
初始点: [0.000000, 0.000000, 0.000000, 0.000000]
迭代次数: 1
最优函数值: 0.000000
最优点: [0.000000, 0.000000, 0.000000, 0.000000]
 
初始点: [1.000000, 1.000000, 1.000000, 1.000000]
迭代次数: 10000
最优函数值: 0.000000
最优点: [0.001029, -0.000103, 0.000499, 0.000498]
 
初始点: [-1.000000, -1.000000, -1.000000, -1.000000]
迭代次数: 10000
最优函数值: 0.000000
最优点: [-0.001029, 0.000103, -0.000499, -0.000498]
 

初始点: [2.000000, 2.000000, 2.000000, 2.000000]
迭代次数: 5559
最优函数值: 0.000000
最优点: [0.000906, -0.000091, 0.000398, 0.000398]
 
初始点: [-2.000000, -2.000000, -2.000000, -2.000000]
迭代次数: 5559
最优函数值: 0.000000
最优点: [-0.000906, 0.000091, -0.000398, -0.000398]
 
四、心得体会
通过本次实验,掌握了共轭梯度法的基本原理和MATLAB编程实现方法。实验中发现,共轭梯度法相比最速下降法和牛顿法在收敛速度上有明显优势。


选取几个与实验二实验三中相同的初始点,并给出相关实验结果的对比及分析(从最优解、最优值、收敛速度(迭代次数)等方面进行比较);

1.	最速下降法:
o	优点:简单易实现。
o	缺点:收敛速度慢,尤其在参数较多表现不佳。
2.	牛顿法:
o	优点:收敛速度快,适用于二次优化问题。
o	缺点:计算复杂,需计算Hessian矩阵,计算量大。
3.	共轭梯度法:
o	优点:收敛速度较快,不需要计算Hessian矩阵,计算量适中。
o	缺点:对初始点较为敏感,在某些情况下可能会失效。


posted @ 2024-05-21 14:29  aallofitisst  阅读(27)  评论(0)    收藏  举报