问题
如何通过其他方法求解根号n—— n \sqrt{n} n
解决
梯度下降
梯度下降主要通过求梯度为0的点,得到凸函数的全局最小值。
首先构建损失函数为凸函数的目标函数,使得目标函数的最小值对应的是我们要求的值,即:
L
=
(
x
2
−
n
)
2
=
x
4
−
2
n
x
2
+
n
2
L=(x^2-n)^2=x^4-2nx^2+n^2
L=(x2−n)2=x4−2nx2+n2
这样就可以保证区间
(
0
,
+
∞
)
(0,+\infty)
(0,+∞)上目标函数是凸函数,并且
n
\sqrt{n}
n处取最小值。
然后对其进行求导:
∇
x
L
=
4
x
3
−
4
n
x
=
4
x
(
x
2
−
n
)
\nabla_x L=4x^3-4nx=4x(x^2-n)
∇xL=4x3−4nx=4x(x2−n)
然后给定一个初始值
x
0
x_0
x0和学习率
α
\alpha
α,梯度下降过程就是:
x
n
+
1
=
x
n
−
α
∇
x
L
x_{n+1}=x_n-\alpha \nabla_x L
xn+1=xn−α∇xL
通过判断
α
∇
L
\alpha \nabla L
α∇L的精确度可以得到不同精确度的结果
python实现:
import random
def sqrt(n):
alpha=0.001
x=random.uniform(0,n/2.)
delta=n
# 差需要不大于0.001才行,即精确度为小数点后2位
while abs(delta)>0.001:
delta=4*x*(x**2-n)
x-=alpha*delta
return x
牛顿迭代
我们要求 x 2 − C x^2-C x2−C的零点,可以随机初始化一个点 ( x i , x i 2 − C ) (x_i,x_i^2-C) (xi,xi2−C),该点要大于 C \sqrt{C} C,然后计算该点处切线的方程,找到其与x轴的交点作为 x i + 1 x_{i+1} xi+1,依次类推。
这里使用C而不是n。
对于
(
x
i
,
x
i
2
−
C
)
(x_i,x_i^2-C)
(xi,xi2−C),切线的斜率,即梯度为
2
x
i
2x_i
2xi,直线方程为
y
=
2
x
i
(
x
−
x
i
)
+
x
i
2
−
C
y=2x_i(x-x_i)+x_i^2-C
y=2xi(x−xi)+xi2−C,其与x轴交点为
(
1
2
(
x
i
+
C
x
i
)
,
0
)
(\frac{1}{2}(x_i+\frac{C}{x_i}),0)
(21(xi+xiC),0),所以更新公式为:
x
i
+
1
=
0.5
∗
(
x
i
+
C
x
i
)
x_{i+1}=0.5*(x_i+\frac{C}{x_i})
xi+1=0.5∗(xi+xiC)
def sqrt(n):
res=n/2.
next=0.5*(res+n/res)
while abs(res-next)>0.001:
res=next
next=0.5*(res+n/res)
return res
袖珍计算器算法
通过一定的转化:
n
=
n
1
2
=
e
1
2
ln
n
\sqrt{n}=n^{\frac{1}{2}}=e^{\frac{1}{2}\ln n}
n=n21=e21lnn
所以可以这样计算:
def sqrt(n):
import math
return math.exp(0.5*math.log(n))
二分查找
就是简单的查找,这里使用LeetCode 69的设置,求整数
def sqrt(n):
left,right=0,n
res=n
while left<=right:
mid=(left+right)//2
if mid*mid<=n:
res=mid
left=mid+1
else:
right=mid-1
return res