暴力循环已死,牛顿迭代法称王

简介: 暴力循环已死,牛顿迭代法称王

一、引言

今天在做力扣每日一题中,有一道题为:

给定一个 正整数 num ,编写一个函数,如果 num 是一个完全平方数,则返回 true ,否则返回 false 。
进阶:不要 使用任何内置的库函数,如  sqrt 。

大名鼎鼎的求平方根,传说中的牛顿迭代法,本篇来看一下具体是怎么进行实现的吧!

二、牛顿迭代法

牛顿迭代法又称为牛顿-拉弗森方法,实际上是由牛顿、拉弗森(又是一个被牛顿大名掩盖的家伙)各自独立提出来的

牛顿-拉弗森方法提出来的思路就是 利用切线是曲线的线性 逼近这个思想。

牛顿、拉弗森们想啊,切线多简单啊,研究起来多容易啊,既然切线可以近似于曲线,我直接研究切线的根不就成了。

如图所示:

6130b16d6bc943e894568a0f30e4dfe3.png

对于上述函数的根来说,我们知道:x = 0

如果用牛顿迭代法怎么进行计算呢?

  • F(x) = x * x
  • F’(x) = 2 * x


db56f86fd7ca425d99e9f0c0b6ef938a.png

首先,牛顿迭代法会找到一个点,比如 x0 ,从 x0 向曲线做直线,交于点 A,做点 A 的切线交于点 x1

这样的话,我们可以得到三个点:x1、x0、A

设A点坐标为 (x0,x0 * x0)、x1点坐标为 (x1, 0)

通过A点和x1点的坐标,可以得出该线的斜率:K = (x0 * x0) / (x0 - x1)


化简得知:


x0 - x1 = ( x0 * x0) / K

x0 - x1 = F(x0) / F’(x0)

x0 - x1 = x0 / 2

x1 = x0 / 2

我们再以 x1 点做上面相同的操作,得到:

  • x2 = x1 / 2

我们无限制的进行上述操作,最终会得到一个公式:Xn+1 = Xn / 2

当无线次的迭代时,我们的 x 值会趋于0

三、平方根

我们上面说到,对于 F(x) = x * x,最终得到的结果为:Xn+1 = Xn / 2

我们想,对于平方根来说:x * x = num

可不可以转化一下,比如:F(x) = x * x - numF'(x) = 2 * x,求这个函数的交点

利用上述我们说的牛顿迭代法,我们可以得知:

F1 点为(x0,x0 * x0 - num)x1 点为(x1,0)

则:

  • K = (x0 * x0 - num) / (x0 - x1)
  • x0 - x1 = (x0 * x0 - num) / K
  • x0 - x1 = F(x0) / F’(x0)
  • x0 - x1 = x0 / 2 - num / (2 * x0)
  • x1 = x0 / 2 + num / (2 * x0)
  • 将x1、x2两点同样进行迭代,得到:x2 = x1 / 2 + num / (2 * x1)

得出式子:Xn+1 = Xn / 2 + num / 2 * Xn

简单来说,选中某个x的初始值,无限进行迭代,最终找到其平方根

F(x) = x * x - num 凸函数的性质,最终的结果应该是:x = sqrt(num)

我们最开始的 x 可以直接取值为 num,因为 num >= sqrt(num)

一般来说,可以判断相邻两次迭代的结果的差值是否小于一个极小的非负数,一般可以取 1e-6 或者 1e-7

四、代码实现

  public boolean isPerfectSquare(int num) {
        if(num == 1){
            return true;
        }
        double ans = num;
        double dir = num;
        while(ans * ans - dir >= 1e-6){
            ans = ans / 2 + dir / (2 * ans);
        }
        int x = (int)ans;
        return x * x == num;
    }

1d70a50edb7640de9be77b45c2908c15.png

五、总结

简单来说,牛顿迭代法通过不断的进行迭代,逐渐趋近于某个目标值

题目一:367. 有效的完全平方数

有兴趣的小伙伴可以去做一下,目前来说对于这种 平方根 题目,面试官最想听到的就是 牛顿迭代法,反手给其一波推理过程,直接抬走面试官。





相关文章
|
机器学习/深度学习 人工智能 自然语言处理
【NLP】Datawhale-AI夏令营Day4打卡:预训练+微调范式
【NLP】Datawhale-AI夏令营Day4打卡:预训练+微调范式
|
JavaScript 前端开发 数据安全/隐私保护
vue element plus Input 输入框
vue element plus Input 输入框
733 0
|
12月前
|
存储 Prometheus 运维
在云原生环境中,阿里云ARMS与Prometheus的集成提供了强大的应用实时监控解决方案
在云原生环境中,阿里云ARMS与Prometheus的集成提供了强大的应用实时监控解决方案。该集成结合了ARMS的基础设施监控能力和Prometheus的灵活配置及社区支持,实现了全面、精准的系统状态、性能和错误监控,提升了应用的稳定性和管理效率。通过统一的数据视图和高级查询功能,帮助企业有效应对云原生挑战,促进业务的持续发展。
285 3
|
9月前
|
机器学习/深度学习 人工智能
NeurIPS 2024:收敛速度最高8倍,准确率提升超30%!华科发布MoE Jetpack框架
在NeurIPS 2024会议上,华中科技大学团队发布了MoE Jetpack框架,旨在解决专家混合(MoE)模型训练中的挑战。该框架通过检查点回收和超球面自适应MoE(SpheroMoE)层两项技术,利用预训练密集模型加速收敛并提高准确性。实验表明,MoE Jetpack在视觉任务上显著提升收敛速度(最高8倍)和准确性(超过30%),为MoE模型的实际应用提供了新动力。尽管存在一些限制,如初始权重依赖密集模型及计算资源需求,但该框架大幅降低了MoE模型的训练成本,提升了其可行性。论文地址:https://arxiv.org/abs/2406.04801。
260 45
|
9月前
|
安全 JavaScript 前端开发
小游戏源码开发之可跨app软件对接是如何设计和开发的
小游戏开发团队常需应对跨平台需求,为此设计了成熟的解决方案。流程涵盖游戏设计、技术选型、接口设计等。首先明确游戏功能与特性,选择合适的技术架构和引擎(如Unity或Cocos2d-x)。接着设计通用接口,确保与不同App的无缝对接,并制定接口规范。开发过程中实现游戏逻辑和界面,完成登录、分享及数据对接功能。最后进行测试优化,确保兼容性和性能,发布后持续维护更新。
|
Java 缓存
response.setHeader用法总结
response.setHeader用法总结
|
11月前
|
数据采集 人工智能 安全
代理IP与人工智能的融合发展
在科技飞速发展的今天,代理IP与人工智能(AI)正以前所未有的速度融合发展,为网络生活带来巨大变化。代理IP通过隐藏真实IP、绕过网络限制、提高访问速度和增强安全性,为AI系统提供了高效的数据访问方式。AI则通过模拟和扩展人的智能,广泛应用于医疗、金融、交通等领域,提高生产效率和生活质量。两者结合,不仅提升了数据采集、处理和模型训练的效率,还为未来创新和发展带来了无限可能。
215 0
|
12月前
|
Kubernetes Linux 开发者
深入探索容器化技术——Docker 的实战应用
深入探索容器化技术——Docker 的实战应用
311 0
|
物联网 Unix Linux
操作系统的演变:从单任务到多任务再到现代并发
操作系统作为计算机的核心软件,其设计和架构的演变反映了计算需求和技术的进步。本文将带领读者穿越时间线,探索操作系统从最初的单任务处理,发展到多任务处理,直至当代复杂的并发和分布式处理系统的历程。我们将一窥各个时代下操作系统的设计哲学、关键技术以及它们如何塑造了今日的数字世界。
314 27
|
缓存 Kubernetes 负载均衡
k8s学习--sessionAffinity会话保持(又称会话粘滞)详细解释与应用
k8s学习--sessionAffinity会话保持(又称会话粘滞)详细解释与应用
1247 0