5.20
工程数学实验牛顿法
• 所花时间:3
• 代码行数:241
• 博客容量:1
• 代码如下:
实验三:Newton法程序设计
一、实验目的
掌握Hesse矩阵的计算方法和Newton法的基本思想及其迭代步骤;学会运用MATLAB编程实现常用优化算法;能够正确处理实验数据和分析实验结果及调试程序。
二、实验内容
(1)求解无约束优化问题: ;
(2)终止准则取 ;
(3)完成Newton法(牛顿法)的MATLAB编程、调试;
(4)选取几个与实验二中相同的初始点,并给出相关实验结果的对比及分析(从最优解、最优值、收敛速度(迭代次数)等方面进行比较);
(5)按照模板撰写实验报告,要求规范整洁。
三、算法步骤、代码、及结果
1. 算法步骤
1. **初始化**:
- 选定一个起始点 x_0 。
- 设置一个小的误差阈值 epsilon ,用于确定算法何时停止。
- 确定最大迭代次数 max,以防止算法无限循环。
2. **迭代过程**:
- 在每一次迭代 k 中:
1. 计算当前点 x_k 处的梯度 g_k 。
2. 计算当前点 x_k 处的Hesse矩阵 H_k 。
3. 如果需要,修正Hesse矩阵,以确保它不是奇异的。
4. 计算一个新的点 x_{k+1} ,通过将当前点 x_k 沿着Newton方向 -H_k^{-1} g_k 移动一定的距离。
5. 检查是否满足停止条件:
- 如果当前点的梯度 | g_k \| 小于设定的误差阈值 epsilon ,则停止迭代。
- 否则,继续迭代。
6. 记录当前目标函数值 f_k = f(x_k) ,以便后续分析。
3. **输出结果**:
- 最终的优化解 x^* = x_{k+1} 。
- 最优值 f(x^*) 。
- 实际迭代次数 k 。
- 目标函数值随迭代次数变化的曲线
2. 代码
function newton_optimization()
% 初始点集合
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 = 100; % 最大迭代次数
% 运行每个初始点
for i = 1:size(initial_points, 1)
x0 = initial_points(i, :)';
fprintf('初始点: [%f, %f, %f, %f]\n', x0);
[x_opt, f_opt, iter, f_vals] = newton_method(@f, @grad_f, @hessian_f, x0, tol, max_iter);
% 打印结果
fprintf('优化后的解:\n');
disp(x_opt');
fprintf('目标函数值:\n');
disp(f_opt);
fprintf('迭代次数:\n');
disp(iter);
fprintf('-------------------------\n');
% 画出最优值随迭代次数变化的曲线
figure;
plot(0:iter-1, f_vals, '-o');
xlabel('迭代次数');
ylabel('目标函数值');
title(sprintf('初始点 [%f, %f, %f, %f]', x0));
end
end
% 目标函数
function y = f(x)
y = (x(1) + 10*x(2))^2 + 5*(x(3) - x(4))^2 + (x(2) - 2*x(3))^4 + 10*(x(1) - x(4))^4;
end
% 目标函数的梯度
function g = grad_f(x)
g = zeros(4,1);
g(1) = 2*(x(1) + 10*x(2)) + 40*(x(1) - x(4))^3;
g(2) = 20*(x(1) + 10*x(2)) + 4*(x(2) - 2*x(3))^3;
g(3) = 10*(x(3) - x(4)) - 8*(x(2) - 2*x(3))^3;
g(4) = -10*(x(3) - x(4)) - 40*(x(1) - x(4))^3;
end
% 目标函数的Hesse矩阵
function H = hessian_f(x)
H = zeros(4,4);
H(1,1) = 2 + 120*(x(1) - x(4))^2;
H(1,2) = 20;
H(1,4) = -120*(x(1) - x(4))^2;
H(2,1) = 20;
H(2,2) = 200 + 12*(x(2) - 2*x(3))^2;
H(2,3) = -24*(x(2) - 2*x(3))^2;
H(3,2) = -24*(x(2) - 2*x(3))^2;
H(3,3) = 10 + 48*(x(2) - 2*x(3))^2;
H(3,4) = -10;
H(4,1) = -120*(x(1) - x(4))^2;
H(4,3) = -10;
H(4,4) = 10 + 120*(x(1) - x(4))^2;
% 加入一个很小的对角矩阵以避免奇异
H = H + eye(4) * 1e-6;
end
% Newton法主程序
function [x, f_val, iter, f_vals] = newton_method(f, grad_f, hessian_f, x0, tol, max_iter)
x = x0;
f_vals = zeros(max_iter, 1);
for iter = 1:max_iter
g = grad_f(x);
H = hessian_f(x);
f_vals(iter) = f(x);
if norm(g) < tol
break;
end
dx = -H\g;
x = x + dx;
end
f_vals = f_vals(1:iter); % 只保留实际迭代次数的值
f_val = f(x);
end
3. 结果
初始点: [0.000000, 0.000000, 0.000000, 0.000000]
优化后的解:
0 0 0 0
目标函数值:
0
迭代次数:
1
-------------------------
初始点: [1.000000, 1.000000, 1.000000, 1.000000]
优化后的解:
0.0028 -0.0003 0.0010 0.0010
目标函数值:
1.3614e-10
迭代次数:
16
-------------------------
初始点: [-1.000000, -1.000000, -1.000000, -1.000000]
优化后的解:
-0.0028 0.0003 -0.0010 -0.0010
目标函数值:
1.3614e-10
迭代次数:
16
-------------------------
初始点: [2.000000, 2.000000, 2.000000, 2.000000]
优化后的解:
0.0038 -0.0004 0.0013 0.0013
目标函数值:
4.2842e-10
迭代次数:
17
-------------------------
初始点: [-2.000000, -2.000000, -2.000000, -2.000000]
优化后的解:
-0.0038 0.0004 -0.0013 -0.0013
目标函数值:
4.2842e-10
迭代次数:
17
四、心得体会
通过编写MATLAB代码并进行实验,我将课堂上学到的Newton法理论知识应用到实际问题中,巩固了对该算法的理解和掌握。 2. MATLAB编程技能的提高: 这次实验增强了我使用MATLAB进行数值计算和优化的能力,尤其是在复杂矩阵计算和优化算法实现方面的技能。 3. 问题解决能力的提升: 在实验过程中遇到的各种问题,如Hesse矩阵奇异性、收敛性等,使我在不断解决问题的过程中提升了自己的分析和解决问题的能力。 4. 对优化算法的更深理解: 通过多次实验和结果分析,我对Newton法在优化问题中的应用有了更深刻的认识,理解了其优缺点以及在实际应用中的一些注意事项。
浙公网安备 33010602011771号