5.2

题目:

上机实验二:最速下降法程序设计

 

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]

posted @ 2024-06-19 18:20  孙锺鸣  阅读(3)  评论(0编辑  收藏  举报