牛顿迭代法与一道经典编程问题
2024-10-12 10:13:39 216人阅读
牛顿迭代法(Newton’s method)又称为牛顿-拉夫逊(拉弗森)方法(Newton-Raphson method)。它是牛顿在17世纪提出的一种在实数域和复数域上近似求解方程的方法。
既然牛顿迭代法能够用来求解方程的根,那么最好还是以方程 x 2 = n <script id="MathJax-Element-197" type="math/tex">x^2=n</script> 为例,来试着求解它的根。为此。
令f ( x ) = x 2 ? n <script id="MathJax-Element-198" type="math/tex"> f(x) = x^2 - n </script>, 也就是相当于求解 f ( x ) = 0 <script id="MathJax-Element-199" type="math/tex">f(x) = 0</script> 的解。如上图所看到的。
首先随便找一个初始值 x 0 <script id="MathJax-Element-200" type="math/tex"> x_0</script>,假设 x 0 <script id="MathJax-Element-201" type="math/tex"> x_0</script>不是解,做一个经过 ( x 0 , f ( x 0 ) ) <script id="MathJax-Element-202" type="math/tex">( x_0,f( x_0))</script> 这个点的切线,与x <script id="MathJax-Element-203" type="math/tex">x</script>轴的交点为x 1 <script id="MathJax-Element-204" type="math/tex">x_1</script>。相同的道理。假设 x 1 <script id="MathJax-Element-205" type="math/tex">x_1</script>不是解,做一个经过( x 1 , f ( x 1 ) ) <script id="MathJax-Element-206" type="math/tex">( x_1,f( x_1))</script>这个点的切线,与x <script id="MathJax-Element-207" type="math/tex">x</script>轴的交点为x 2 <script id="MathJax-Element-208" type="math/tex">x_2</script>。 以此类推。以这种方式得到的x i <script id="MathJax-Element-209" type="math/tex">x_i</script>会无限趋近于 f ( x ) = 0 <script id="MathJax-Element-210" type="math/tex">f(x) = 0</script> 的解。
推断x i <script id="MathJax-Element-211" type="math/tex">x_i</script>是否是f ( x ) = 0 <script id="MathJax-Element-212" type="math/tex">f(x) = 0</script>的解有两种方法: 一是直接计算f ( x i ) <script id="MathJax-Element-213" type="math/tex">f(x_i) </script>的值推断是否为0 <script id="MathJax-Element-214" type="math/tex">0</script>,二是推断前后两个解x i <script id="MathJax-Element-215" type="math/tex">x_i</script>和x i ? 1 <script id="MathJax-Element-216" type="math/tex">x_{i-1}</script>是否无限接近。
经过( x i , f ( x i ) ) <script id="MathJax-Element-217" type="math/tex">(x_i, f(x_i))</script>这个点的切线方程为f ( x ) = f ( x i ) + f ′ ( x i ) ( x ? x i )
<script id="MathJax-Element-218" type="math/tex; mode=display">f(x) = f(x_i) + f‘(x_i)(x - x_i)</script>当中。f ′ ( x ) <script id="MathJax-Element-219" type="math/tex">f‘(x)</script>为f ( x ) <script id="MathJax-Element-220" type="math/tex">f(x)</script>的导数,本题中为2 x <script id="MathJax-Element-221" type="math/tex">2x</script>。令切线方程等于 0 <script id="MathJax-Element-222" type="math/tex">0</script>。就可以求出
x i + 1 = x i ? f ( x i ) f ′ ( x i )
<script id="MathJax-Element-223" type="math/tex; mode=display">x_{i+1}=x_i - \frac{f(x_i)}{f‘(x_i)}</script>
继续化简
x i + 1 = x i ? x 2 i ? n 2 x i = x i ? x i 2 + n 2 x i = x i 2 + n 2 x i
<script id="MathJax-Element-224" type="math/tex; mode=display">x_{i+1}=x_i -\frac{x_i^2 - n}{2x_i} = x_i - \frac{x_i}{2} + \frac{n}{2x_i} = \frac{x_i}{2} + \frac{n}{2x_i}</script>
基于上述迭代公式,我们其实给出了一个求平方根的算法。其实,这也的确是非常多语言中内置的开平方函数的实现方法。
Leetcode上也有一道经典面试题目涉及到开平方函数的实现。例如以下
基于我们已经给出的牛顿迭代法,以下就可来编程解决该问题了。演示样例代码例如以下
class Solution {
public :
int mySqrt (int x) {
if (x ==0 )
return 0 ;
double pre;
double cur = 1 ;
do
{
pre = cur;
cur = x / (2 * pre) + pre / 2.0 ;
} while (abs(cur - pre) > 0.00001 );
return int (cur);
}
};
<script type="text/javascript"> $(function () { $(‘pre.prettyprint code‘).each(function () { var lines = $(this).text().split(‘\n‘).length; var $numbering = $(‘
‘).addClass(‘pre-numbering‘).hide(); $(this).addClass(‘has-numbering‘).parent().append($numbering); for (i = 1; i <= lines; i++) { $numbering.append($(‘
‘).text(i)); }; $numbering.fadeIn(1700); }); }); </script>
牛顿迭代法与一道经典编程问题
order role 5.5 line 1.0
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉:
投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。
×
https://www.u72.net/daima/nces1.html