牛顿法和拟牛顿法是是求解最优化问题(函数)的常用方法,具有收敛速度快的特点。
牛顿法
考虑无约束最优化问题:其中
x
为目标函数的极小值点
假设 f(x) 具有二阶连续偏导数,若第 k 次迭代值为 xk ,则可将 f(x) 在 xk 附近二阶泰勒展开:二阶泰勒公式可以理解为多项式对目标函数的逼近
f(x)=f(xk)+f′(xk)(x−xk)+f′′(xk)(x−xk)2
这个公式可以理解为等同于目标函数,最优化也就是求解近似解,从极值入手(同上,求解极值点)。那么求极值的必要条件就是一阶导等于0,二阶导不为0,极大极小看方向。
那么设
f(x)=0
;
求近似解的过程:每次迭代从
xk
开始,下一个极小值点就是
xk+1
,再令函数为0。
如图:
为了实现方便,推导一下这个公式:
f(xk)+f′(xk)(x−xk)+f′′(xk)(x−xk)2=0
x=xk−f′(xk)f′′(xk)
既有:
xk+1=xk−f′(xk)f′′(xk)∗12
注:以上只讨论了变量个数为1的情形
下面以求平方根的例子理解这个公式:
为构建目标函数,引入:
f(x)=x2−c
f′(x)=2x
目标变转化为求根问题(变化过程如上图)
一样的泰勒展开,只不过展开到一阶就可以了,二阶没有意义:
彼时的函数为
xk+1=xk−f(xk)f′(xk)
如求解1024:
c=1024 :,假设 x0=10
x1=x0−f(x0)f′(x0)=10−102−10242∗10=56.2
x2=x1−f(x1)f′(x1)=56.2−56.22−10242∗56.2=37.2103
⋮
32.3648
32.0021
32
每次迭代误差降低:
迭代停止有一个条件可以是 Xk 的变化率趋于0
代码:
const double breaker = 0.0001;
const int NewtonMethod(unsigned long long int number){
double Xn;
double Xnn = 10.00;
do
{
Xn = Xnn;
Xnn= Xn-0.5*((Xn*Xn-number)/Xn);
std::cout<<Xnn<<std::endl;
}while(std::abs(Xn-Xnn)>breaker);
return (int)Xnn;
}
int main(){
unsigned long long int number = 10000000000;
//std::cin>>number;
//std::cout<<std::sqrt(number)<<std::endl;
std::cout<<NewtonMethod(number)<<std::endl;
}
其他
测试标题