我读了计算任意数字的平方根的方法,算法如下:
double findSquareRoot(int n) {
double x = n;
double y = 1;
double e = 0.00001;
while(x-y >= e) {
x = (x+y)/2;
y = n/x;
}
return x;
}
关于此方法的问题是
如何计算平方根?我不明白这背后的数学。 x=(x+y)/2 and y=n/x
如何收敛于n的平方根。解释这个数学。
此算法的复杂性是什么?
答案 0 :(得分:3)
很容易看出你是否进行了一些运行并打印了x和y的连续值。例如100:
50.5 1.9801980198019802
26.24009900990099 3.8109612300726345
15.025530119986813 6.655339226067038
10.840434673026925 9.224722348894286
10.032578510960604 9.96752728032478
10.000052895642693 9.999947104637101
10.000000000139897 9.999999999860103
请注意,诀窍是如果x
不是 n
的平方根,那么它高于或低于真实根,n/x
永远在另一边。因此,如果计算x
和n/x
的中点,它将更接近真实的根。
关于复杂性,它实际上是无限的,因为真正的根将永远不会到达。这就是你拥有e
参数的原因。
答案 1 :(得分:3)
这是Newton's method用于计算n
的平方根的典型应用。您正在计算序列的限制:
x_0 = n
x_{i+1} = (x_i + n / x_i) / 2
您的变量x
是当前字词x_i
,而变量y
是n / x_i
。
要了解为什么必须计算此限制,您需要考虑函数:
f(x) = x^2 - n
您想要找到此功能的根目录。它的衍生物是
f'(x) = 2 * x
和牛顿的方法为您提供了公式:
x_{i+1} = x_i - f(x_i) / f'(x_1) = ... = (x_i + n / x_i) / 2
为了完整起见,我在这里复制@ rodrigo答案的基本原理,并结合我对它的评论。如果您想忘记Newton的方法并尝试单独理解此算法,这将非常有用。
诀窍是如果
x
不是n
的平方根,那么它就是。y = n/x
近似值位于真实根之上或之下,而(x+y)/2
始终位于真实根之上 另一边。因此,如果您计算x
的中点,它将是。{ 比这两个近似中最差的更接近真根 (y
或x
)。当y
和d
足够接近时,您就完成了。
这也可以帮助您找到算法的复杂性。假设r
是两个近似值中最差的与真实根(x+y)/2
的距离。然后,中点r
和d/2
之间的距离最多为log(|n-sqrt(n)|/epsilon)
(如果您绘制一条直线来显示它,它会对您有所帮助)。这意味着,每次迭代,距离减半。因此,最坏情况的复杂性是对数w.r.t。到初始近似的距离和所寻求的精度。对于给定的程序,它是
{{1}}
答案 2 :(得分:1)
我认为所有信息都可以是found in wikipedia。
基本思想是,如果x高估了非负实数S的平方根,那么S / x将被低估,因此可以合理地预期这两个数字的平均值可以提供更好的近似。
每次迭代时,此算法会在答案中将正确的数字加倍,因此复杂性与所需精度的对数呈线性关系。
为什么会这样?如上所述here,如果你将进行无限次迭代,你会得到一些值,让我们把它命名为L.L必须满足等式L =(L + N / L)/ 2(如在算法中),所以L = sqrt(N)。如果你担心收敛,你可以计算每次迭代的平方相对误差(Ek是错误,Ak是计算值):
Ek =(Ak / sqrt(N) - 1)²
如果:
Ak =(Ak-1 + N / Ak-1)/ 2和Ak = sqrt(N)(sqrt(Ek)+ 1)
你可以得出Ek的递归关系:
Ek = Ek-1²/ [4(sqrt(Ek-1)+ 1)²]
并且它的限制是0,因此A1,A2 ...序列的限制是sqrt(N)。
答案 3 :(得分:1)
数学解释是,在小范围内,算术平均值是几何平均值的合理近似值,用于计算平方根。随着迭代越接近真正的平方根,算术平均值和几何平均值之间的差异消失,近似值变得非常接近。这是我最喜欢的Heron算法版本,它首先将输入 n 归一化,范围为1≤ n < 4,然后展开循环一定数量的迭代,保证收敛。
def root(n):
if n < 1: return root(n*4) / 2
if 4 <= n: return root(n/4) * 2
x = (n+1) / 2
x = (x + n/x) / 2
x = (x + n/x) / 2
x = (x + n/x) / 2
x = (x + n/x) / 2
x = (x + n/x) / 2
return x
我讨论了几个计算my blog的平方根的程序。