牛顿迭代法简介
参考资料:
牛顿迭代法是一种求方程f(x)=0近似解的一种方法。
假设我们现在得到的近似解是xi,然后我们画出在(xi,f(xi))点与曲线相切的直线,该直线与x轴相交会得到一个xi+1。根据导数与直线斜率的关系,我们可以得到:f'(xi)=(f(xi))/(xi-xi+1)。整理后得到如下递推式:xi+1=xi-f(xi)/f'(xi)。根据本递推式我们可以知道如果曲线平滑,随着迭代次数的增加,xi将愈发接近方程的解。牛顿迭代法的收敛率是平方级的,即每次迭代精度会翻倍。然而在方程有多个解时可能最后收敛的结果只会确定少数的解。
应用一:求解平方根
我们可将问题化简为求x2-n=0的根的问题。代入上述递推式,我们得到xi+1=(xi+n/xi)/2
在具体实现时只需注意设定合适的精度即可。
代码如下:
1 #include <stdio.h> 2 #include <iostream> 3 using namespace std; 4 double abs(double x){ 5 if (x>0) 6 return x; 7 else 8 return -x; 9 } 10 double sqrt_newton (double n){ 11 const double exp=1e-15; 12 double x=1; 13 while (true){ 14 double x1=(x+n/x)/2; 15 if(abs(x1-x)<exp)break; 16 x=x1; 17 } 18 return x; 19 } 20 int main (){ 21 double n=2; 22 double x1=sqrt_newton(n); 23 printf("%llf",x1); 24 return 0; 25 }
例题:
LeetCode 69. x 的平方根
截图如下:
代码如下:
1 class Solution { 2 public: 3 int mySqrt(int x) { 4 double x0=x; 5 double x1=1; 6 int t=50; 7 double x2; 8 while(t--){ 9 x2=(x1+x0/x1)/2; 10 x1=x2; 11 } 12 return (int)x1; 13 } 14 };
应用二:求解整数平方根
我们仍然考虑一个类似于牛顿迭代的过程,但需要在边界条件上稍作修改。如果 x在迭代的过程中上一次迭代值得近似解变小,而这一次迭代使得近似解变大,那么我们就不进行这次迭代,退出循环。
1 #include <stdio.h> 2 #include <iostream> 3 using namespace std; 4 int isqrt_newton (double n){ 5 bool de=false;//判断是否为递降 6 int x=1; 7 while (true){ 8 double x1=(x+n/x)/2; 9 if(x==x1||x1>x&&de)break;//如果上一次是递减,这一次结果增加,则退出 10 de=x1<x; 11 x=x1; 12 } 13 return x; 14 } 15 int main (){ 16 int n=4; 17 int x1=isqrt_newton(n); 18 printf("%d",x1); 19 return 0; 20 }
应用三:高精度平方根
迭代方法不变,但因为迭代次数较多我们需要选取特定的x0=2[0.5*log2n]作为我们的迭代初值,这样可以快速逼近近似值。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 分享4款.NET开源、免费、实用的商城系统
· 全程不用写代码,我用AI程序员写了一个飞机大战
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了
· 上周热点回顾(2.24-3.2)