如果说最速下降法是站在“构造搜索方向和步长”的角度考虑迭代问题的,那么牛顿法则是从“直接构造迭代关系式”的角度上思考问题的。
牛顿法
之前在工程优化设计与Matlab实现——优化设计的数学基础中提到过泰勒展开式,泰勒展开的根本意图就是用一个多项式近似一个函数。牛顿法就利用了泰勒展开式的前几项来构造了一个迭代公式,来寻求使目标函数等于0的极小值点。
Point 1 一维情况下的牛顿法
将函数
忽略掉高阶无穷小,有:
但对上式求一阶导数,并令一阶导数等于0,有:
可以推出:
所以我们推出了一个由
牛顿法将每次求得的
Point 2 多维情况下的牛顿法
对于一元函数,我们用了一元函数的泰勒展开,现在面临多维函数,当然就要用多维函数的泰勒展开式了。
将函数
其中
同样忽略掉高阶无穷小,求一阶导数,并令导数等于0,得:
Point 3 牛顿法和一维搜索中的二次插值法
我们隐约觉得牛顿法和一维搜索中的二次插值法有些相像,二者都是用一个插值函数取近似一个函数,然后找出函数的极值点,通过若干次迭代使插值函数极值点越来越靠近目标函数的极值点。而二者之间的区别是,一维搜索中的二次插值法只有一个方向,它可以通过函数值的比较、取舍区间来缩小范围,但牛顿法却要面临着多维问题,就没办法像二次插值那样将问题一分为二、选择去留,所以就直接通过迭代的方式来靠近极小值点。
Point 4 牛顿法的搜索方向和步长
虽然牛顿法是站在“构造迭代公式”的角度上进行的迭代,但是其迭代公式的形式与搜索迭代的公式异曲同工。
牛顿法迭代公式:
搜索迭代公式:
通过对比我们可以认为:
牛顿法中,每一次迭代的步长为
Point 5 牛顿法的特点
对于某些函数,牛顿收敛速度快,计算量较大(梯度和Hessian矩阵),对初值要求高(需要尽可能的离终点近)。对于二次函数,如果Hessian矩阵正定,牛顿法计算很有效,但是对于二次函数或者说二次性不好的函数,又不能保证Hessian矩阵正定,牛顿法很有可能失效。
Point 6 牛顿法的栗子
利用牛顿法,求目标函数
主程序如下:
clc;
clear all;
close all;
%设置精度、函数、起始点
e = 1e-8;
x0 = [0;0];
%-----------调用牛顿法-----------%
fprintf('nn牛顿法:n')
[NiuDunFa_x, NiuDunFa_xf, NiuDunFa_n] = NiuDunFa(e, x0);
fprintf('牛顿法极值点:n%fn%fn%fn%fn',NiuDunFa_x)
fprintf('牛顿法极值:%fn牛顿法迭代次数:%dn', NiuDunFa_xf, NiuDunFa_n)
目标函数定义如下:
function f = func(x)
f = x(1)^2 + x(2)^2 - x(1)*x(2) - 10*x(1) - 4*x(2) + 60;
牛顿法函数定义如下:
%-----------牛顿法---主函数-----------%
function [NiuDunFa_x, NiuDunFa_xf, NiuDunFa_n] = NiuDunFa(e, x0)
syms t1 t2 t3 t4
x = [t1;t2];
f = func(x);
%求x0处jacobian矩阵、hessian矩阵的值
yf = jacobian(f,x)'; %求jacobian矩阵的转置
hf = hessian(f,x); %求hessian矩阵
k = 1; %迭代开
n = 0; %迭代次数统计
while k == 1
n = n + 1;
yf_x0 = subs(yf, x, x0); %将x0代入
hf_x0 = subs(hf, x, x0); %将x0代入
x1 = x0 - inv(hf_x0) * yf_x0; %得x1
f_x1 = subs(f, x, x1); %将x1代入,求得函数值
f_x0 = subs(f, x, x0); %将x0代入,得x0处的梯度
%判断迭代是否终止
if abs(f_x1-f_x0) <= e
break;
else
x0 = x1;
end
end
NiuDunFa_x = vpa(x1);
NiuDunFa_xf = vpa(f_x1);
NiuDunFa_n = n;