二分法求方程的根_快速求解方程的根——二分法与牛顿迭代法

今天是周四高等数学专题的第7篇文章。

之前的文章和大家聊了许多数学上的理论,今天和大家聊点有用的东西。

我们都知道,工业上的很多问题经过抽象和建模之后,本质还是数学问题。而说到数学问题就离不开方程,在数学上我们可以用各种推算、公式,但是有没有想过在计算机领域我们如何解一个比较复杂的方程

如果之前没有想过,那你可能得想一想,因为以后很有可能会在面试题当中遇到。

二分法

我们要介绍的第一个方法是二分法。

说到二分法大家应该都不陌生,老实说我第一次在高数课本上看到二分法这三个字的时候,其实是蛮震惊的。后来当我又在统计等数学书上看到许多其他算法之后,才慢慢习以为常。在我转行做算法的这几年当中,我越来越意识到,数学的重要性。虽然这并不意味着你一定要成为数学高手,但如果你还没毕业的话,至少数学课好好听讲还是很有必要的。

我们说回二分法,如果学过二分法,会觉得这是一个非常简单的算法,但如果你们做过LeetCode第四题,又会发现纯二分法的题也可以这么难。如果只是单纯地讲解二分法的原理,我们是很难完完全全将这个算法吃透的。为了达到这点,我思考了很久,最终决定仿照看山是不是山的禅宗理论,将二分法也分成三个层次。

首先是第一个层次,即我们每次将一个东西分成两半

这个应该是我们最初也是最直观的观念,比如最经典的金币问题。说是我们有若干个个硬币,其中有一个是金币,金币的重量更重,其他的硬币重量相等。我们只有一个天平,怎么样用最少的次数找出金币。

c5e8fb6431716e1cf4b666abbce640cb.png

在这个问题当中,我们需要不停地将硬币分成两个部分,用天平锁定其中的一个。通过不断重复上述操作,快速找到答案。

在第二个层次当中,二分法不再是简单地将物体一分为二,而是一个折半查找的函数。这也是本文重点要介绍的解方程的方法。

如果有函数 f(x) ,它在区间[a, b]上递增或者递减,并且 f(a)*f(b) < 0。那么我们知道函数必然有一个等于0的解,而且这个解我们可以用二分法来求近似解。

1ecacaea0f7c87b5e63ac336e1302119.png

在上图当中,f(x)递增,并且f(a) < 0, f(b) > 0。我们继续获取了a和b的中点 x0。根据上图,我们又得到 f(x0) > 0,所以我们可以把 x0 看成是新的b。于是我们继续寻找a和 x0 的中点,重复上述过程,由于我们最大的误差就是区间的长度,所以当我们区间的长度缩减到足够小,那么就说明我们已经找到了一个足够近似的解。

在二分法当中,我们没进行一次二分迭代,区间的长度就会缩减一半,这是一个指数级的缩减。所以即使一开始的区间很大,经过二分迭代也可以迅速缩减,得到一个非常精准的结果,并且和泰勒级数一样,除了能得到一个足够精确的值之外,还能得到误差的范围。

我们再深入一些思考,会发现有些条件我们还可以再松动松动。比如我们真的需要函数是严格递增或者递减吗?比如我们来看下面这张图:

9dc25fc2b0cf768d3c1f6d8341279b9c.png

在(b2, b1)区间内,函数并不是严格递减的,而是先递减再递增的。但是这并不会影响结果的正确性,因为在这个问题当中,二分法并不是通过判断 f(x0) 和a处函数值的大小来缩小区间的,而是通过f(x0)的正负性。也就是说,只需要满足 f(a)*f(b) < 0,并且函数连续且等于0的点只有一个,就可以使用二分来进行查找。

深入思考,就进入了二分法的第三个层次,即放下递增的限制,回到折半这个原始的概念上来。

二分法的本质就是查找空间折半,至于函数递增或者是数组当中元素递增都只是表象,只是我们进行折半的条件。换句话说如果我们能找到其他的条件来折半搜索空间,那么我们一样可以得到二分的效果,并不用拘泥于是否有序。

也就是说我们绕了一圈,最后又回到了将“物体”一分为二这个最基本的概念上来。只是我们经过这么一波折腾,表面上看和最初的理解一样,但其实早已天差地别了。

没想到算法领域也能玩一把禅宗,看山是山,看山不是山,最后回到看山还是山。

牛顿迭代法

看完了二分法,我们再来看另一个快速求根的方法,和二分法一样,它也是迭代逼近的方法,但是逼近的速度更快。这个方法最早是牛顿提出的,因此也被称为牛顿迭代法,我想牛顿这个名字写出来,大家应该都能get到它的分量。

牛顿迭代法的名头看起来很唬人,但是原理真的不难,说白了只有一句话,就是通过切线去逼近,比如我们来看下图:

1a8dbf68586a8aa8229b3d59dea81862.png

在上图当中,我们要求 f(x)=0 的根,我们先找到了一个 xn点,我们在 xn 处进行求导取得了它的切线。显然只要这个切线的斜率不为0,那么我们一定可以获得它和x轴的交点。我们将这个交点作为下一个取值,也就是 xn+1的点。我们重复上述过程进行迭代,很快就可以得到一个足够接近的解。

对于点 xn 处的切线而言,它的斜率是 f'(xn),截距b就是 f(xn)。它的切线方程很好得到,就是:

35c963a3d928fb7537bcb15c702a5067.png

我们利用这个方程,可以求到它和x轴的交点,也就是xn+1的值:

b6685cc9b0ad6dc1ef7e4bf4a6a3196d.png

解下这个方程,可以得到:

e5529ed9dbcc62a9f8ac3fb61954b863.png

上面这个式子就是牛顿迭代法的迭代公式,这是一个非常牛的方法,比二分法要厉害得多,因为它的收敛速度更快,并且计算也并不复杂。

我们来看下它的威力,我们来看知乎鍵山小鞠[1]大神回答里的一个例子:

我们利用 f(x) = sin(x) 来求 π 的值,我们都知道在 [π/2, π] 区间内, sin(π) = 0,所以我们求 f(x) = 0 的解就可以间接求出π的值。

在这个问题下,迭代公式为:

34405e74ea8e4c6557cce6bf66433e62.png

我们以 x0 = 3 为迭代起始点,进行迭代,得到的结果如下:

x0=3.0(1位)x1=3.1411...(4位)x2=3.14159265357...(11位)x3=3.1415926535897932384626433832795020...(34位)x4=3.14159265358979323846264338327950288419716939937510582097494459230781640628620899862803482534211706786...(102位)x5=3.1415926535897932384626433832795028841971693993751058209749445923078164062862089986280348253421170679821480865132823066470938446095505822317253594081284811174502841027019385211055596446229489549303819644288109756659334461284756482337867831652712019091456485669234603486104543266482133936072602491412734...(301位)

可以看到,短短经过五次迭代,我们计算得到的圆周率已经超过了300位,每次迭代我们的精度都会提升三倍以上,这是非常令人震惊的。

无法收敛的情况

但令人遗憾的是并不是所有方程使用牛顿迭代法都可以有这么好的效果,对于一些方程,甚至可能会出现越走越偏的情况。我们再举个例子,比如方程:

ebf2a5709679e63dbbe7ac6cc4f3be43.png

如果我们画出它的迭代过程,是这样的:

6f2a363d53dfc793680fd5a2daa74163.png

我们观察一下上面的迭代公式也可以看得出来,我们把 -1/f'(xn) 看成是系数,我们对 f(x) 求导算下这个系数,可以得到它的系数是3*x^{2/3},观察一下就能发现随着x的增大,这个系数也是在增大的。也就是说,随着我们的迭代,这个值会变得越来越大,也就意味着我们的振幅越来越大,也就离收敛越来越远。

虽然少数情况下牛顿迭代法不能收敛,但是大多数情况下它效果都非常好。二分法固定每次缩短一半的区间,而牛顿迭代法的迭代效率往往更高,一般情况下使用牛顿迭代法可以获得更快的收敛速度。和二分法相比,牛顿迭代法的公式也并不难写,并且它在机器学习当中也有应用,学会它真的非常划算!

今天关于二分和牛顿迭代法的文章就到这里,如果觉得有所收获,请顺手点个关注或者转发吧,你们的举手之劳对我来说很重要。

参考资料

[1]

知乎: "https://www.zhihu.com/question/20690553"

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/261717.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

关于android开发环境的创建

最近想暑假找个实习单位&#xff0c;想想java android方面的应该比c、C要好点&#xff0c;然后就想重操旧业学习android 大三的时候我学过一个学期的android知识。当时创建开发环境我很快就弄好了&#xff0c;但是环境创建险些让我崩溃。 环境搭建包括四步&#xff1a; 1、JDK安…

getchar()和EOF总结

大师级经典的著作&#xff0c;要字斟句酌的去读&#xff0c;去理解。以前在看K&R的The C Programming Language(SecondEdition) 第1.5节的字符输入/输出&#xff0c;被getchar()和EOF所迷惑了。可能主要还是由于没有搞清楚getchar()的工作原理和EOF的用法。因此,感觉很有必…

Android多种View动画:EasyAndroidAnimations

&#xfeff;&#xfeff;Android多种View动画&#xff1a;EasyAndroidAnimations EasyAndroidAnimations是Android的一个动画库&#xff0c;使用起来简单方便&#xff0c;EasyAndroidAnimations将一个Android View以各种形式的动画动起来。 其中如图&#xff1a; EasyAndroidA…

python中configparser详解_Python中的ConfigParser模块使用详解

1.基本的读取配置文件-read(filename) 直接读取ini文件内容-sections() 得到所有的section&#xff0c;并以列表的形式返回-options(section) 得到该section的所有option-items(section) 得到该section的所有键值对-get(section,option) 得到section中option的值&#xff0c;返…

关于ubuntu无法启动nginx的问题

在ubuntu13.04上使用apt方式安装nginx发现无法启动nginx&#xff0c;也不报错 查看nginx运行状态&#xff0c;显示未启动 搜索无果&#xff0c;想起了原来的遇到的一个问题&#xff0c;那时候是安装了nginx和lighthttpd服务器&#xff0c;导致nginx无法启动的情况&#xff0c;提…

MVC中validateRequest=false不起作用

MVC Request.QueryString 客户端 潜在危险 在MVC中如果传递xml等参数时&#xff0c;会报“从客户端中检测到有潜在危险的Request.QueryString值”的错误&#xff0c;无法提交参数&#xff0c;在web.Config的Pages节点或者aspx页面中添加validateRequest"false"貌似不…

C语言之基本算法32—鞍点

//数组/*题目&#xff1a;求随意矩阵的全部鞍点。并统计个数。&#xff08;在矩阵中&#xff0c;一个数在所在行中是最大值&#xff0c; 在所在列中是最小值。则被称为鞍点。&#xff09; 如&#xff1a; 1 2 34 5 6 7 8 9 当中&#xff0c;a[1][3]3是该矩阵唯一的…

django python3.6_Django+mysql+python3.6.5 Windows

1.下载py365https://www.python.org/downloads/windows/(原来有2.7.x版本 直接修改环境变量即可&#xff0c;需要多个python环境可以使用pyevn)2.安装mysql2.1下载https://dev.mysql.com/downloads/mysql/5.7.html#downloads解压&#xff1a;mysql-5.7.22-winx642.2配置环境变量…

STL - 底层实现

一、STL六大组件1&#xff09;容器&#xff08;Container&#xff09;2&#xff09;算法&#xff08;Algorithm&#xff09;3&#xff09;迭代器&#xff08;Iterator&#xff09;4&#xff09;仿函数&#xff08;Function object&#xff09;5&#xff09;适配器&#xff08;A…

Oracle以SQL方式导出导入(转移)数据

为什么80%的码农都做不了架构师&#xff1f;>>> 导出源数据 源数据库为Oracle 9g使用SQL Developer导出数据库的表结构和数据&#xff0c;导出成sql文件。这里的源Oracle和目标Oracle的编码是否相同&#xff0c;如果表字段里有时间类型的那么还要注意两库的日期格式…

产品经理应该干些啥?

产品经理的工作&#xff0c;总结起来就三件事&#xff1a; 1、知道做什么 2、知道怎么做 3、让别人去做 先来看“知道做什么”。 许多产品经理其实不知道该做什么&#xff0c;整日被动的应付上面安排下来的工作&#xff0c;一旦出现工作的断顿&#xff0c;就会感觉无所事…

oppo售后解锁恢复工具.zip_OPPO手机4个不为人知的小技巧,全知道的竟然不到1%,令人唏嘘...

随着科技的发展速度加快&#xff0c;智能手机产品也越做越高端。手机里面也包含着很多很实用的技巧&#xff0c;却没有多少人知道&#xff0c;简直就是白白的浪费呀&#xff01;应用分屏一个很好用的功能&#xff0c;利用它我们可同时进行两种操作&#xff0c;比如&#xff1a;…

matlab中方波信号的谐波表示

matlab中方波信号的谐波表示 一.数学运算 二.matlab代码 t-7:0.001:7; %x(t)中t取值范围为【-7,7】 T11; T4; w2*pi/T; a02*T1/T; Ninput(请输入谐波数); Xta0*ones(1,length(t)); for k1:NXtXt2*a0*sinc(k*a0)*cos(k*w*t); end plot(t,Xt);三.运行结果 四。结论 很明显…

C语言学习笔记三

// C 学习笔记//日期&#xff1a;2013-5- 主讲&#xff1a;//记录&#xff1a;ant //备注&#xff1a;课堂学习笔记//// switch ... case语句也可以用来实现分支的处理&#xff0c;使用方法如下 switch(表达式&#xff09; { …

美到极致是疯狂

这是今天和校招新同事交流时的总结&#xff0c;希望校招新同事能够回顾&#xff0c;也能够写出自己的总结。 一、什么是代码高手&#xff1f;你怎么证明自己是代码高手&#xff1f; 知道许多代码技巧、JS炫彩技巧的人大有人在。你知道多少个.net函数&#xff0c;这一点都没有意…

websocket onclose方法什么时候触发_WebSocket断开重连解决方案,心跳重连实践

WebSocket是前后端交互的长连接&#xff0c;服务器可以主动向客户端推送信息&#xff0c;客户端也可以主动向服务器发送信息&#xff0c;是真正的双向平等对话&#xff0c;属于服务器推送技术的一种。项目中&#xff0c;我们经常会使用WebSocket和服务器建立持久的连接。但是前…

matlab计算离散卷积

一.卷积的数学运算 &#xff08;1&#xff09;定义法 &#xff08;2&#xff09;图解法 &#xff08;3&#xff09;竖式乘法 二.matlab中计算离散卷积使用conv()函数 conv(a,b) 计算序列a与b的卷积 以上图中的习题为例 matlab代码如下&#xff1a; n1[ -2 -1 0 1 2 3 4 5]; …

黑马程序员_Java基础GUI

------- <a href"http://www.itheima.com" target"blank">android培训</a>、<a href"http://www.itheima.com" target"blank">java培训</a>、期待与您交流&#xff01; ---------- GUI:Graphical User Interf…

Maven中使用本地JAR包

为什么80%的码农都做不了架构师&#xff1f;>>> 在Maven项目中使用本地JAR包有两种方法&#xff1a; 1、使用system scope <dependencies><dependency><groupId>org.richard</groupId><artifactId>my-jar</artifactId><ver…

python文件读取方法read(size)的含义是_在Python中可使用read([size])来读取文件中的数据,如果参数size省略,则读取文件中的()。(4.0分)_学小易找答案...

【单选题】文本文件存储的是(),由若干文本行组成,通常每行以换行符 \n 结尾。(4.0分)【单选题】()属性是返回被打开文件的访问模式。(4.0分)【单选题】重力坝是由砼或( )修筑而成的大体积档水建筑物。【单选题】模式()的用途是打开一个文件用于追加。如果该文件已存在,文件指针…