6.6学习任务
进行了工程数学实验二的练习
实验二:最速下降法
一、实验目的
通过最速下降法的程序设计,为今后的约束优化方法的学习和编程奠定基础;掌握负梯度方向的定义和最速下降法的迭代公式 ;通过此次实验,进一步巩固最速下降法的基本原理和思想。
二、实验内容
(1)求解无约束优化问题: ;
(2)终止准则取 ;
(3)完成最速下降法(负梯度法)的MATLAB编程、调试;
(4)要求选取多个不同的初始点,并给出迭代次数,最优函数值等相关信息,有能力的同学尝试画出最优值随迭代次数变化的曲线图;
(5)按照模板撰写实验报告,要求规范整洁。
三、算法步骤、代码、及结果
1. 算法步骤
1. 初始化:选择初始点 �0x0,设置收敛条件 �ϵ 和最大迭代次数 \text{max_iter}。
2. 计算梯度:在当前点 ��xk 处计算目标函数的梯度 ∇�(��)∇f(xk)。
3. 判断终止条件:检查梯度的范数是否小于收敛条件,或者迭代次数是否达到最大迭代次数。如果是,则停止迭代,当前点 ��xk 即为最优解。
4. 更新步骤:根据梯度的反方向调整当前点,通常采用下面的更新公式: ��+1=��−��∇�(��)xk+1=xk−αk∇f(xk) 其中,��αk 是步长(也称为学习率),可以通过回溯线搜索等方法确定。
5. 重复迭代:重复步骤 2-4,直到满足终止条件。
2. 代码
function [x_opt, f_opt, iterations] = steepest_descent(f, grad_f, x0, epsilon, max_iter)
% f: 目标函数
% grad_f: 目标函数的梯度
% x0: 初始点
% epsilon: 收敛条件,当梯度的范数小于epsilon时停止迭代
% max_iter: 最大迭代次数
iterations = 0;
x_opt = x0;
while true
gradient = grad_f(x_opt); % 计算梯度
if norm(gradient) < epsilon || iterations >= max_iter
break;
end
% 更新x
alpha = backtracking_line_search(f, grad_f, x_opt, gradient); % 使用回溯线搜索确定步长
x_opt = x_opt - alpha * gradient;
iterations = iterations + 1;
end
f_opt = f(x_opt); % 计算最优函数值
end
function alpha = backtracking_line_search(f, grad_f, x, gradient)
% 回溯线搜索确定步长
alpha = 1;
rho = 0.5; % 衰减系数
c = 0.1; % 控制衰减程度
while f(x - alpha * gradient) > f(x) - c * alpha * gradient' * gradient
alpha = rho * alpha;
end
end
示例目标函数
% 目标函数和梯度定义
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];
% 初始点和参数设置
x0_list = [randn(4,1), randn(4,1)*10]; % 随机选择两组不同的初始点
epsilon = 1e-6;
max_iter = 1000;
for i = 1:size(x0_list, 2)
x0 = x0_list(:,i);
% 调用最速下降法
[x_opt, f_opt, iterations] = steepest_descent(f, grad_f, x0, epsilon, max_iter);
fprintf('Initial point: (%f, %f, %f, %f)\n', x0(1), x0(2), x0(3), x0(4));
fprintf('Optimal point: (%f, %f, %f, %f)\n', x_opt(1), x_opt(2), x_opt(3), x_opt(4));
fprintf('Optimal function value: %f\n', f_opt);
fprintf('Iterations: %d\n', iterations);
fprintf('\n');
end