emmmm
大学的时候微积分导数没学好,
以及小学初中高中的数学基本还给老师了【扶额
导致我现在对算法这种东西理解无力。
所以先从简单的开始吧。
用二分查找和牛顿法分别实现一个简单的求根号方法。
先用系统自带的 sqrt 方法做对照组
{
let sqrt = {
dft: (num)=>{
console.time("dft");
console.log(Math.sqrt(num));
console.timeEnd("dft");
},
bs: (num)=>{
},
nt: (num)=>{
}
,
all: (num)=>{
sqrt.dft(num);
sqrt.bs(num);
sqrt.nt(num);
}
};
sqrt.all(666);
}
二分查找很简单
给定一个范围(1 和 目标数字),不断取中值,然后根据精度返回就行了。
bs: (num)=>{
// 二分查找
console.time("bs");
let min;
let max;
min = Math.min(1, num);
max = Math.max(1, num);
while (true) {
let result = (max - min) / 2 + min;
if (min * min === num || min === result || max === result)
break;
if (result * result > num)
max = result;
else
min = result;
}
console.log(min);
console.timeEnd("bs");
},
牛顿法:
已知
f(x)=x^2
求当f(x) = n
的时候x
的值,即求这个函数与 x
轴的交点
f(x) = x^2 -n
先求导数
f'(x)=x^2-n
然后随机取一个点,比如 x0
,他的 纵坐标为 x0^2 - n
,斜率为 2x0
过 (x0,x0^2 -b)
斜率为 2x0
的直线的方程为
f(x) = 2x0(x-x0) + x0^2 - n
即
f(x) = 2x0x - x0^2 -n
其与 x
轴的交点的横坐标为 0 = 2x0x - x0^2 -n
即
x = (x0^2 + n)/2x0
也就是说先随机取一个点,迭代一次以后得到上述值,检查一遍精度是否符合要求。如果符合,则直接返回,否则继续循环迭代,
这个点暂时就先取 1 吧
即
nt: (num)=>{
console.time("nt");
let x0 = 1;
while (true) {
x1 = x0 / 2 + num / (2 * x0);
if (x0 === x1)
break;
x0 = x1;
}
console.log(x0);
console.timeEnd("nt");
},
然后试一下看看输出和计算时间