在JavaScript中实现带容差的二进制搜索?
我试图找到一个介于在JavaScript中实现带容差的二进制搜索?,javascript,math,while-loop,binary-search,Javascript,Math,While Loop,Binary Search,我试图找到一个介于min和max之间的数字。我只知道(通过使用more方法)我猜测的数字是高于还是低于传递的数字。我需要找到的数字可以是十进制,这让我很紧张,因为平均二进制搜索似乎主要关注整数的业务 我写的算法是在不使用数组的情况下进行二进制搜索的尝试。在我看来,经典二进制搜索之间的区别在于,搜索的值和索引已合并到同一个任务中 var容差=0; var、最小值、最大值、当前值、所需值; 函数搜索(){ 尝试=0; 最小值=0; 最大值=100; 需要=Math.random()*最大值; 电流
min
和max
之间的数字。我只知道(通过使用more
方法)我猜测的数字是高于还是低于传递的数字。我需要找到的数字可以是十进制,这让我很紧张,因为平均二进制搜索似乎主要关注整数的业务
我写的算法是在不使用数组的情况下进行二进制搜索的尝试。在我看来,经典二进制搜索之间的区别在于,搜索的值和索引已合并到同一个任务中
var容差=0;
var、最小值、最大值、当前值、所需值;
函数搜索(){
尝试=0;
最小值=0;
最大值=100;
需要=Math.random()*最大值;
电流=(最大-最小)/2;
而(!accept()&&trys<100){
如果(更多(当前))
最小值=电流;
其他的
最大值=电流;
电流=最小值+((最大-最小)/2);
尝试++;
}
结果();
}
功能更多(n){
返回n<所需;
}
函数接受(){
return Math.abs(当前需要)在搜索范围内的数字时,很难比二进制搜索做得更好
假设范围始终为已知/相似,则可以使用more()函数或clamp函数在search()函数之前进行验证。请参阅此链接
如果范围可以急剧变化,可以使用某种指数函数来找到“好的范围”
- 范围0-100
- 范围101至1000
- 范围从1001到20000
- 等等
你也可以考虑将你的容忍度设置为一个百分比,或者设置为一个“好小数”
要知道,搜索带有x位小数的数字(即0到1000范围内的123.45)和搜索0到100000范围内的12345时,您将获得相同的效果
由于“最坏情况”的尝试次数为⌈log2(n+1)⌉. 尝试100次可以让您精确地找到0到n=1267650600228229401496703205375之间的数字。因为您有小数,所以对于所需精度的每一个小数,您需要将该数字除以10
0.xxxxxx精度将为您留下一个0到12676506002282294014967032的范围,在此范围内,您可以在不到100次的尝试中找到您的号码
如果我的计算正确..很难比二进制搜索更好地搜索范围内的数字
假设范围始终为已知/相似,则可以使用more()函数或clamp函数在search()函数之前进行验证。请参阅此链接
如果范围可以急剧变化,可以使用某种指数函数来找到“好的范围”
- 范围0-100
- 范围101至1000
- 范围从1001到20000
- 等等
你也可以考虑将你的容忍度设置为一个百分比,或者设置为一个“好小数”
要知道,搜索带有x位小数的数字(即0到1000范围内的123.45)和搜索0到100000范围内的12345时,您将获得相同的效果
由于“最坏情况”的尝试次数为⌈log2(n+1)⌉. 尝试100次可以让您精确地找到0到n=1267650600228229401496703205375之间的数字。因为您有小数,所以对于所需精度的每一个小数,您需要将该数字除以10
0.xxxxxx精度将为您留下一个0到12676506002282294014967032的范围,在此范围内,您可以在不到100次的尝试中找到您的号码
如果我的计算是正确的..当在实区间上进行二进制搜索时,不需要检查是否相等,而是继续细化搜索区间,直到它足够小
// Generated by CoffeeScript 1.10.0
(function() {
var eps, hi, lo, mid, more, secret;
// This is your tolerance value.
eps = 0.01;
// The binary search routine will never get to see this.
secret = 45.63;
more = function(test) {
return test > secret;
};
lo = 0;
hi = 100;
while (hi - lo > eps) {
mid = lo + ((hi - lo) / 2);
if (more(mid)) {
hi = mid;
} else {
lo = mid;
}
}
console.log(mid);
}).call(this);
输出:45.635986328125
当值超出范围时,输出将等于lo
或hi
,其中等于意味着它们的绝对差值将小于eps
另见:
由于实数集是稠密的,我们通常无法找到确切的目标值,这一点应该很清楚。然而,我们可以很快找到一些x,比如f(x)在“否”和“是”之间的边界范围内。我们有两种方法来决定何时终止:当搜索空间小于某个预定边界(例如10^-12)时终止,或者执行固定次数的迭代
当在实区间上进行二进制搜索时,不需要检查是否相等,而是不断细化搜索区间,直到它足够小为止
// Generated by CoffeeScript 1.10.0
(function() {
var eps, hi, lo, mid, more, secret;
// This is your tolerance value.
eps = 0.01;
// The binary search routine will never get to see this.
secret = 45.63;
more = function(test) {
return test > secret;
};
lo = 0;
hi = 100;
while (hi - lo > eps) {
mid = lo + ((hi - lo) / 2);
if (more(mid)) {
hi = mid;
} else {
lo = mid;
}
}
console.log(mid);
}).call(this);
输出:45.635986328125
当值超出范围时,输出将等于lo
或hi
,其中等于意味着它们的绝对差值将小于eps
另见:
由于实数集是稠密的,我们通常无法找到确切的目标值,这一点应该很清楚。然而,我们可以很快找到一些x,比如f(x)在“否”和“是”之间的边界范围内。我们有两种方法来决定何时终止:当搜索空间小于某个预定边界(例如10^-12)时终止,或者执行固定次数的迭代
我会将accept函数更改为Math.abs(当前需要)@Wikunia你是对的-这有点草率。可能是@Rishav的重复,但这不适用。我这里的主要问题是,这可以改进吗?或者有更好的方法实现同样的目标吗?就个人而言,我宁愿在执行搜索函数之前验证数字是否在范围内。你可以使用你的more()当然,如果您愿意,也可以使用钳制函数,例如(请参见链接),我会将accept函数更改为Math.abs(当前需要)@Wikunia您是对的-这有点草率。可能是@Ris的重复