软件工程日报(5.7)
题目:
上机实验二:最速下降法程序设计
1、基本要求
通过最速下降法的程序设计,为今后的约束优化方法的学习和编程奠定基础;掌握负梯度方向的定义和最速下降法的迭代公式;通过此次实验,进一步巩固最速下降法的基本原理和思想。
2、主要内容
(1)求解无约束优化问题:;
(2)终止准则取;
(3)完成最速下降法(负梯度法)的MATLAB编程、调试;
(4)要求选取多个不同的初始点,并给出迭代次数,最优函数值等相关信息,有能力的同学尝试画出最优值随迭代次数变化的曲线图;
(5)按照模板撰写实验报告,要求规范整洁。
3、操作要点
(1)最速下降法Matlab的实现;
(2)学会分析实验结果;
(3)撰写实验报告;
4、主要仪器设备
微机及Matlab软件
代码:
1. 算法步骤
1. steepest_descent 函数
1. 定义目标函数 f 和其梯度 grad_f:
目标函数 f 和梯度 grad_f 是给定的,分别用于计算函数值和梯度。
2. 初始化初始点集合 initial_points:
定义了一组初始点用于梯度下降算法。
3. 设置终止准则和最大迭代次数:
使用 tol 作为梯度范数的阈值,当梯度范数小于 tol 时停止迭代;max_iter 为最大迭代次数。
4. 遍历初始点:
对于每个初始点,调用 gradient_descent 函数进行梯度下降优化,并打印结果。
5. 绘制最优值随迭代次数变化的曲线图:
使用 plot 函数为每个初始点绘制最优值随迭代次数变化的曲线图。
2. gradient_descent 函数
1. 初始化:
将初始点 x0 赋给 x,并初始化一个用于存储每次迭代函数值的数组 f_values。
2. 迭代过程:
对于每次迭代,计算当前点的梯度 grad,并将函数值 f(x) 存储在 f_values 中。
3. 检查终止条件:
如果梯度的范数小于 tol,则停止迭代。
4. 线搜索:
调用 line_search 函数找到最佳的步长 alpha。
5. 更新解:
使用步长 alpha 和梯度 grad 更新解 x。
6. 返回结果:
返回优化后的解 x_opt、最优函数值 f_val、迭代次数 iter 以及函数值数组 f_values。
3. line_search 函数
1. 初始化步长和参数:
设置初始步长 alpha 为 1,以及 c、rho 作为线搜索的参数。
2. 线搜索过程:
在 while 循环中,检查 f(x - alpha * grad) 是否满足Armijo-Goldstein条件(即是否小于 f(x) - c * alpha * (grad' * grad))。
3. 更新步长:
如果不满足Armijo-Goldstein条件,则将步长 alpha 乘以 rho 进行缩减。
4. 返回结果:
当满足Armijo-Goldstein条件时,返回步长 alpha。
2. 代码
function steepest_descent()
% ¶¨ÒåÄ¿±êº¯Êý
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] = gradient_descent(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] = gradient_descent(f, grad_f, x0, tol, max_iter)
x = x0;
f_values = zeros(max_iter, 1);
for iter = 1:max_iter
grad = grad_f(x);
f_values(iter) = f(x);
if norm(grad) < tol
break;
end
alpha = line_search(f, grad_f, x, grad);
x = x - alpha * grad;
end
x_opt = x;
f_val = f(x_opt);
f_values = f_values(1:iter);
end
function alpha = line_search(f, grad_f, x, grad)
alpha = 1;
c = 1e-4;
rho = 0.9;
while f(x - alpha * grad) > f(x) - c * alpha * (grad' * grad)
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.000002
最优点: [0.030411, -0.003037, 0.015144, 0.015166]
初始点: [-1.000000, -1.000000, -1.000000, -1.000000]
迭代次数: 10000
最优函数值: 0.000002
最优点: [-0.030411, 0.003037, -0.015144, -0.015166]
初始点: [2.000000, 2.000000, 2.000000, 2.000000]
迭代次数: 10000
最优函数值: 0.000002
最优点: [0.030465, -0.003042, 0.015171, 0.015193]
初始点: [-2.000000, -2.000000, -2.000000, -2.000000]
迭代次数: 10000
最优函数值: 0.000002
最优点: [-0.030465, 0.003042, -0.015171, -0.015193]
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 单元测试从入门到精通
· 上周热点回顾(3.3-3.9)
· winform 绘制太阳,地球,月球 运作规律