最优化方法-无约束优化算法(最速下降法)matlab实现

一、前言

最速下降法 ,又称为梯度法,是一种无约束求解多元函数极小值的方法。最速下降法的起源可以追溯到19世纪,最早由数学家Cauchy在1847年提出。随着计算机技术的发展,最速下降法在20世纪50年代逐渐应用于各种优化问题,尤其是在机器学习领域得到了广泛的采用。

最速下降法的核心思想是利用函数的梯度信息来指导搜索方向。在当前点计算函数的梯度,确定下降方向,即当前点的负梯度方向。

二、定义

基于梯度信息来寻找函数的局部最小值。它从当前点出发,取函数在该点下降最快的方向(即负梯度方向)作为搜索方向,然后沿此方向进行一维搜索,找到使函数值最小的步长,从而更新当前点。

  1. 选取初始点x(0),并给定终止误差ε>0。
  2. 计算当前点的梯度∇f(x),若∇f(x)≤ε,则停止迭代,输出当前点作为近似最优解;否则,进行下一步。
  3. 取搜索方向d(k)=-∇f(x(k)).
  4. 进行一维搜索,求步长αk,这里提供公式.使得f(x(k)+αkp(k))=minf(x(k)+αp(k))
  5. 更新当前点x(k+1)=x(k)+αkd(k)并令k=k+1,转步骤2。

三、代码实现

Matlab 复制代码
% 梯度下降法求解二次函数最小值
f = @(x1,x2) 3/2 * x1.^2 + 1/2*x2.^2 - x1*x2 - 2*x1;

% 初始化参数
x0 = -2; % 初始x值
y0 = 4; % 初始y值
alpha = 1; % 初始步长(学习率)
tol = 1e-3; % 容差,用于判断梯度是否足够小
max_iter = 1000; % 最大迭代次数

% 初始化变量并预分配内存(如果需要存储每次迭代的结果)
x = zeros(1, max_iter);
y = zeros(1, max_iter);
f_val = zeros(1, max_iter);
iter = 0;
x(iter+1) = x0;
y(iter+1) = y0;
f_val(iter+1) = f(x0,y0);
hesse = [3,-1;-1,1];

% 梯度计算函数(向量化形式,尽管在这个例子中向量化并没有带来性能提升)
grad_f = @(x_vec) [3*x_vec(1)-x_vec(2)-2; x_vec(2)-x_vec(1)];

% 迭代过程
while iter < max_iter-1
    % 计算当前点的梯度(使用向量化输入,但输出仍然是分开的x和y梯度)
    grad = grad_f([x(iter+1), y(iter+1)]);

    % 检查梯度是否足够小,以判断是否达到停止条件
    if norm(grad) < tol
        fprintf('达到停止条件,迭代结束。\n');
        break;
    end

    alpha = (grad.' * grad) / (grad.' * hesse * grad);
    % 更新x和y的值
    x(iter+2) = x(iter+1) - alpha * grad(1);
    y(iter+2) = y(iter+1) - alpha * grad(2);
    
    % 计算新的函数值(可选,用于监控收敛过程)
    f_val(iter+2) = f(x(iter+2),y(iter+2));
    
    % 增加迭代次数
    iter = iter + 1;
end

% 输出最终结果
if iter == max_iter-1
    fprintf('达到最大迭代次数,迭代结束。\n');
end
fprintf('最终结果: x = %.6f, y = %.6f, f(x, y) = %.6f\n', x(iter+1), y(iter+1), f_val(iter+1));

% 如果需要,可以绘制收敛过程
figure;
plot(1:iter+1, f_val(1:iter+1), '-o');
xlabel('迭代次数');
ylabel('f(x, y)');
title('梯度下降法收敛过程');

需要输入函数表达式和梯度表达式,然后 设置初始点,步长默认为1,如果想要减少迭代次数可以设置的小一点。

这里基于课本习题第一题为例,用最速下降法极小化,默认步长为1,通过线性搜索法算出最佳步长,这里的公式为

Matlab 复制代码
    alpha = (grad.' * grad) / (grad.' * hesse * grad);

hesse为海色 (**Hesse)矩阵,**grad为梯度,可以直接算出下次迭代的步长。

结果:

以及曲线图

然后在右侧查看每次迭代的函数值

这里迭代6次就结束了。

四、总结

通过之后的学习,了解到最速下降法效率较低,收敛慢等问题,下一篇将介绍牛顿法达到一步迭代出结果。

如有问题还请评论区指正,感谢观看!

相关推荐
青い月の魔女13 分钟前
数据结构初阶---二叉树
c语言·数据结构·笔记·学习·算法
java1234_小锋40 分钟前
MyBatis如何处理延迟加载?
java·开发语言
林的快手1 小时前
209.长度最小的子数组
java·数据结构·数据库·python·算法·leetcode
FeboReigns1 小时前
C++简明教程(10)(初识类)
c语言·开发语言·c++
学前端的小朱1 小时前
处理字体图标、js、html及其他资源
开发语言·javascript·webpack·html·打包工具
千天夜1 小时前
多源多点路径规划:基于启发式动态生成树算法的实现
算法·机器学习·动态规划
从以前1 小时前
准备考试:解决大学入学考试问题
数据结构·python·算法
.Vcoistnt2 小时前
Codeforces Round 994 (Div. 2)(A-D)
数据结构·c++·算法·贪心算法·动态规划
摇光932 小时前
js高阶-async与事件循环
开发语言·javascript·事件循环·宏任务·微任务
沐泽Mu2 小时前
嵌入式学习-QT-Day09
开发语言·qt·学习