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

今天是周四高等数学专题的第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安…

Android多种View动画:EasyAndroidAnimations

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

关于ubuntu无法启动nginx的问题

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

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

为什么80%的码农都做不了架构师&#xff1f;>>> 导出源数据 源数据库为Oracle 9g使用SQL Developer导出数据库的表结构和数据&#xff0c;导出成sql文件。这里的源Oracle和目标Oracle的编码是否相同&#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);三.运行结果 四。结论 很明显…

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]; …

Maven中使用本地JAR包

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

折半查找法(二分查找法)

一.举例 二.算法时间复杂度 假设一共有n个元素 第一次折半元素个数变为n/2; 第二次折半元素个数变为n/4; 第三次折半元素个数变为n/8&#xff1b; 。。。。。 第k次折半元素个数变为n/2^k; 。。。。。 假设k次找到&#xff0c;即为n/2^k1&#xff1b; klog2(n); 三.函数实现 …

悬浮截图软件_Windows最好用截图工具,QQ第一,它第二

大家平时可能都有自己惯用截图工具&#xff0c;比如 Snipaste、PickPick、QQ 截图&#xff0c;还有 Windows 自带的 WinShiftS 截图快捷键等等。如果你不是工具控&#xff0c;那一般来说 QQ 截图和 Windows 快截键就是最简单方便的两个截图工具了。但是真要说简单方便&#xff…

[摘记]数值方法04——函数求值

注&#xff1a;以下来自《C数值算法一书》&#xff0c;仅对章节内容做摘要&#xff0c;为的是给自己扫盲&#xff0c;不涉及算法。 这里只讨论一些最清晰明了的一般方法。 1. 级数与其收敛性 思想&#xff1a;解析函数可在某点x0的邻域内展开成级数&#xff1a;。用这个级数可以…

java文件处理之压缩,分割

http://blog.csdn.net/ycg01/article/details/1366648 java文件处理之压缩,分割 标签&#xff1a; javaexceptionimportnullbytefile2006-11-05 00:30 1574人阅读 评论(1) 收藏 举报分类&#xff1a;点滴&#xff08;12&#xff09; 版权声明&#xff1a;本文为博主原创文章&am…

Hook KiUserExceptionDispatcher参数指针错误的问题

跟了一个晚上,终于解决了 大概要实现的是用这个函数替换ntdll中的KiUserExceptionDispatcher,实现方法如下: VOID NTAPI KiUserExceptionDispatcher(PEXCEPTION_RECORD pExcptRec,PCONTEXT pContext) { DWORD retValue; if (RtlDispatchException(pExcptRec,pContext)) { retVa…

Docker image Introduce

Docker 的image是运行的基本.例如我们build一个image时, 在Dockerfile每条指令会产生一个可读写的image, 下一条指令使用上一条指令产生的image为基础, 继续产生image(然后删除上一个image), 如果指令没有对image有修改的动作, 那么可以使用image cache. 所有的指令执行完, 生成…

vue 筛选组件_记一个复杂组件(Filter)的从设计到开发

此文前端框架使用 rax&#xff0c;全篇代码暂未开源&#xff08;待开源&#xff09;原文链接地址&#xff1a;Nealyang/PersonalBlog前言貌似在面试中&#xff0c;你如果设计一个 react/vue 组件&#xff0c;貌似已经是司空见惯的问题了。本文不是理论片&#xff0c;更多的是自…

python的正则表达式 re

2019独角兽企业重金招聘Python工程师标准>>> 原文发表在&#xff1a; http://luy.li/2010/05/12/python-re/ 延伸阅读&#xff1a;python的 内建函数 和 subprocess 。此文是本系列的第三篇文章了&#xff0c;和之前一样&#xff0c;内容出自官方文档&#xff0c;但…

福克斯保养明细

福克斯轮胎厚度&#xff1a; 胎冠厚度在13mm左右(胎冠花纹深7mm、胎冠厚6mm&#xff09;&#xff0c; 胎侧厚度5mm。 现在的轿车轮胎一般胎面胶层厚度都比较厚&#xff0c;以165/70R13 锦湖KR19轮胎为例:花纹深度为7毫米&#xff0c;缓冲层1&#xff0d;1.5毫米&#xff0c;冠带…

USACO 1.1 Your Ride Is Here

今天开始切USACO 加油 /* ID: aznfy1 PROG: ride LANG: C */ #include <iostream> #include <fstream> #include <string> #include <stdio.h>using namespace std;char a[10],b[10];int main() {freopen("ride.in","r",stdin);f…

Mysql支持的数据类型(总结)

2019独角兽企业重金招聘Python工程师标准>>> 一.数值类型 Mysql支持所有标准SQL中的数值类型&#xff0c;其中包括严格数据类型(INTEGER,SMALLINT,DECIMAL,NUMBERIC)&#xff0c;以及近似数值数据类型(FLOAT,REAL,DOUBLE PRESISION),并在此基础上进行扩展。 扩展后增…