泰勒公式
本质就是多项式逼近推广到无穷级数逼近,在实际应用中对于具有复杂形式的函数,我们常常希望用较为简单的函数形式表示它,那多项式就是这种简单的形式。
用吴文俊的话说就是:把质的困难转化成量的复杂。
展开前求解函数的值很困难,展开后是幂函数的线性组合,虽然有很多很多项,但是每一项都是幂函数,因此每一项都容易求解。于是只要对展开后的求和,就能得到展开前的函数的值
本质就是对于一个无穷阶连续可导的函数,它的各阶导数值就给出了这个函数的所有信息,你可以就把这个函数想象为无穷阶的多项式函数,系数定了这个函数也就定了。
泰勒公式可以说是用函数在某一点的导数逐次逼近函数的过程。
概述
牛顿法的基本思想是利用迭代点处的一阶导数(梯度)和二阶导数(Hessen矩阵)对目标函数进行二次函数近似,然后把二次模型的极小点作为新的迭代点,并不断重复这一过程,直至求得满足精度的近似极小值。牛顿法的速度相当快,而且能高度逼近最优值。牛顿法分为基本的牛顿法和全局牛顿法。
基本牛顿法
基本牛顿法是一种用导数求解的算法,它每一步的迭代方向都是沿着当前点函数值下降最快的方向。主要是为了解决非线性优化问题,其收敛速度比梯度下降速度更快。其需要解决的问题可以描述为:对于目标函数f(x),在无约束条件的情况下求它的最小值。
当 n=1 时
对于一个需要求解的优化函数
f(x)
,求函数的极值的问题,可以转化为求导函数
f′(x)=0
,对函数
f(x)
进行泰勒展开到二阶:
对上式求导并令其为0,
即
这个就是牛顿法的更新公式。若从初始值
x=x0
开始进行迭代,将得到
x
的一个序列:
当 n>1 时
此时,可以将
x
写成
对上式求导并令其为0,由于 f(x) 中的 x 是一个向量,
求导后得:
令:
此时的 gk 为一个向量, Hk 为一个矩阵。
令上式 f′(x)=0 ,即 f′(x)=f′(xk)+f′′(xk)(x−xk)=0
即
算法
1.给定终止误差值
0≤ϵ≪1
,初始化
x0∈Rn
,设
k=0
.
2.计算
gk=∇f(xk)
,若
∥gk∥≤ϵ
,则停止,输出
x∗≈xk
3.计算
hk=∇2f(xk)
,求关于
gk
与
hk
的比,
hkr=−gk,r=−gkh−1k
4.令
xk+1=xk+rk,k=k+1
,并转向2
优缺点
它比传统的梯度下降算法收敛速度明显要快。
阻尼牛顿法
牛顿法最突出的优点是收敛速度快,具有局部二阶收敛性,但是,基本牛顿法初始点需要足够“靠近”极小点,否则,有可能导致算法不收敛。这样就引入了阻尼牛顿法,阻尼牛顿法最核心的一点在于可以修改每次迭代的步长,通过沿着牛顿法确定的方向一维搜索最优的步长,最终选择使得函数值最小的步长。
算法
1.给定终止误差值
0≤ϵ≪1,δ∈(0,1),σ∈(0,0.5)
,初始化
x0∈Rn
,设
k=0
.
2.计算
gk=∇f(xk)
,若
∥gk∥≤ϵ
,则停止,输出
x∗≈xk
3.计算
Gk=∇2f(xk)
,求关于
gk
与
Gk
的比,
Gkr=−gk
4.设
mk
是不满足下列不等式的最小非负整数
m
:
4.令 αk=δmk,xk+1=xk+αkrk,k=k+1 ,并转向2
Armijo搜索
阻尼牛顿法是基于Armijo的搜索,满足Armijo准则:
给定:
δ∈(0,1),σ∈(0,0.5)
,令步长因子
αk=δmk
代码示例:
函数: f(x)=x2−3x+1 ,最小值为 f(32)=−14=−0.25
package newtonmethod;
/**
* Newton法
*
* @author zhangdapeng
*
*/
public class NewtonMethod {
private double x0;// 初始点
private double e;// 误差阈值
private double maxCycle;// 最大循环次数
/**
* 构造方法
*
* @param x0初始值
* @param e误差阈值
* @param maxCycle最大循环次数
*/
public NewtonMethod(double x0, double e, double maxCycle) {
this.x0 = x0;
this.e = e;
this.maxCycle = maxCycle;
}
/**
* 原始函数
*
* @param x变量
* @return 原始函数的值
*/
public double getOriginal(double x) {
return x * x - 3 * x + 2;
}
/**
* 一次导函数
*
* @param x变量
* @return 一次导函数的值
*/
public double get1Derivative(double x) {
return 2 * x - 3;
}
/**
* 二次导函数
*
* @param x变量
* @return 二次导函数的值
*/
public double get2Derivative(double x) {
return 2;
}
/**
* 利用牛顿法求解
*
* @return
*/
public double getNewtonMin() {
double x = this.x0;
double y = 0;
double k = 1;
while (k <= maxCycle) {
y = this.getOriginal(x);
double d1 = this.get1Derivative(x);
if (Math.abs(d1) <= e) {
break;
}
double d2 = this.get2Derivative(x);
x = x - d1 / d2; // 更新x的值
k++;
}
return y;
}
public static void main(String args[]) {
NewtonMethod newton = new NewtonMethod(0, 0.00001, 100);
System.out.println("基本牛顿法求解:" + newton.getNewtonMin());
}
}
package newtonmethod;
/**
* 阻尼牛顿法
*
* @author zhangdapeng
*
*/
public class DampedNewtonMethod {
private double x0;
private double delta;
private double sigma;
private double e;
private double maxCycle;
public DampedNewtonMethod(double x0, double delta, double sigma, double e, double maxCycle) {
this.x0 = x0;
this.delta = delta;
this.sigma = sigma;
this.e = e;
this.maxCycle = maxCycle;
}
/**
* 原始函数
*
* @param x变量
* @return 原始函数的值
*/
public double getOriginal(double x) {
return x * x - 3 * x + 2;
}
/**
* 一次导函数
*
* @param x变量
* @return 一次导函数的值
*/
public double get1Derivative(double x) {
return 2 * x - 3;
}
/**
* 二次导函数
*
* @param x变量
* @return 二次导函数的值
*/
public double get2Derivative(double x) {
return 2;
}
/**
* 利用牛顿法求解
*
* @return
*/
public double getDampedNewtonMin() {
double x = this.x0;
double y = 0;
double k = 1;
// 更新公式
while (k <= maxCycle) {
y = this.getOriginal(x);
double d1 = this.get1Derivative(x);
if (Math.abs(d1) <= e) {
break;
}
double d2 = this.get2Derivative(x);
double dr = -d1 / d2;// 搜索的方向
double m = 0;
double mk = 0;
while (m < 20) {
double left = this.getOriginal(x + Math.pow(this.delta, m) * dr);
double right = this.getOriginal(x) + this.sigma * Math.pow(this.delta, m) * this.get1Derivative(x) * dr;
if (left <= right) {
mk = m;
break;
}
m++;
}
x = x + Math.pow(this.delta, mk) * dr;
k++;
}
return y;
}
public static void main(String args[]) {
DampedNewtonMethod gNewton = new DampedNewtonMethod(0, 0.55, 0.4, 0.00001, 100);
System.out.println("全局牛顿法求解:" + gNewton.getDampedNewtonMin());
}
}
http://www.cnblogs.com/liuwu265/p/4713987.html
http://blog.csdn.net/u011584941/article/details/48163229