首页 > 代码库 > 牛顿法
牛顿法
看最优化的文章时总能看到牛顿法和梯度下降法等基础算法,这里对牛顿法做个总结。
牛顿法一般的用途有:1、求方程的根;2、求极值
求方程的根
并不是所有的方程都有求根公式,或者求根公式很复杂,导致求解困难。利用牛顿法,可以迭代求解。
原理是利用泰勒公式,在x0处展开,且展开到一阶,即f(x) = f(x0)+(x-x0)f‘(x0)
求解方程f(x)=0,即f(x0)+(x-x0)*f‘(x0)=0,求解x = x1=x0-f(x0)/f‘(x0),因为这是利用泰勒公式的一阶展开,f(x) = f(x0)+(x-x0)f‘(x0)处并不是完全相等,而是近似相等,这里求得的x1并不能让f(x)=0,只能说f(x1)的值比f(x0)更接近f(x)=0,于是乎,迭代求解的想法就很自然了,可以进而推出x(n+1)=x(n)-f(x(n))/f‘(x(n)),通过迭代,这个式子必然在f(x*)=0的时候收敛。整个过程如下图:
求极值
根据函数极值的必要条件可知,要求一个函数f(x)的极值,可以令f‘(x)=0求方程得到极小值点,于是可以采用类似于上面的牛顿法求方程,迭代式子为:
下面编写程序对上面的各举一个例子说明:
#!/usr/bin/python # -*- coding:utf8 -*- import random #f(x) = x^2 - 4*x + 3 lastval = random.uniform(-10,10) def solution(func1, func2) : global lastval val = 0 for index in xrange(0, 100) : val = lastval - func1(lastval) * 1.0 / func2(lastval) if abs(val - lastval) < 0.000001 : break lastval = val print "times of iterate : %s" % index return val if __name__ == "__main__" : print "solution of equation x^2 - 4*x + 3 =0 : %s" % solution(lambda x: x**2 - 4*x + 3, lambda x: 2*x - 4) print "minimum of f(x) = x^2 - 4*x + 3 : %s" % solution(lambda x: 2*x - 4, lambda x: 2)
执行结果:
可以看到牛顿法解方程需要迭代的次数一直在变,这是跟初始值有关;求极值例子比较简单,只一次迭代就完成了,其实相同条件下牛顿法求极值比梯度下降法要更快!牛顿法的一大优点就是它比梯度下降法更具有全局判断能力,在二阶导数的作用下,从函数的凹凸性出发,直接搜索怎样到达极值点;而梯度法是从初始点的领域开始判断,在局部进行最速下降方向,然后步步逼近极值;所以往往会导致梯度下降法比牛顿法迭代的次数更多。
文章参考于http://blog.csdn.net/luoleicn/article/details/6527049
http://www.zhihu.com/question/19723347
牛顿法