最优化方法-无约束优化算法(最速下降法)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次就结束了。

四、总结

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

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

相关推荐
IvanCodes2 分钟前
Python 基础语法(四):循环结构与流程控制
开发语言·python
OPEN-F3 分钟前
C++工程化:编译链接、调试与性能优化
开发语言·c++
欧特克_Glodon12 分钟前
OpenCV计算机视觉开发入门与实践<二十九>:grabCut算法分割图像
opencv·算法·计算机视觉·图像分割·grabcut 算法
坐吃山猪16 分钟前
【多线程】什么时候必须/推荐使用Thread类
java·开发语言
一只小阿乐25 分钟前
java 快速上手开发 2
java·开发语言·前端
张宇Joaquin30 分钟前
灵渠测试工具-urma_perftest
java·开发语言
高彬1 小时前
SAP ECC6.0 对接 C# web Services服务
开发语言·前端·c#·sap
方方洛1 小时前
vllm教程-02-核心原理
人工智能·算法·vllm
张小姐的猫1 小时前
【C++开发脚手架】 —— Jsoncpp上手
java·linux·开发语言·网络·c++·tcp/ip·udp
一晌小贪欢1 小时前
python-第20天:关键字参数与不定长参数
java·开发语言·前端·python·数据可视化·函数参数·python办公