二进制搜索与一次固定一位数

时间:2017-12-14 07:44:21

标签: algorithm matlab scientific-computing

问题:我想搜索x_0的实数f(x_0)=0。我们只知道f是单调递增的,无衍生的,x_0是真正的积极,但不是非常大,因此程序不会终止。

当我没有参加算法课程时,我为此编写了一个程序,让我们称之为alternative search

要做的是初始化步长h并从左侧开始增量。如果f(x_0)>0,则退后一步,从现在开始按h/10递增。换句话说,一次修复x_0一个数字,并在步长非常小时终止。

这种方法与二分法搜索(或有人称之为二分法)相比如何?

我的直觉告诉我,每次alternative search解决问题的十分之一,与一半相比,速度会慢一些。应该是对的,是吗?

1 个答案:

答案 0 :(得分:2)

如果您只对即时问题的答案感兴趣,请跳至第二部分 在第一部分中,我将解释如何在您的案例中实际使用二进制搜索。

二进制搜索

首先,这个问题无法单独通过二分搜索来解决,因为你需要一个区间[a,b],其中你的解x *与f(x *)= 0所在。 例如,可以使用指数搜索算法找到这样的间隔:

  • 以值x0开始,使得f(x)< 0
  • 只要f(x)< 0,将x乘以2 (或另一个固定因子> 1)

这样,你的算法在最多log2(x * / x0)步骤之后终止,其值为x,我们知道f(x)&lt; 0和f(2x)>因此,我们可以在二进制搜索中使用这个区间[x,2x]。

另外,如果你的解x *是一个实数,二进制搜索一般不能给你精确的解,只有一个具有任意精度的近似值(更具体地说是一个区间),作为一个实数可以有无数的数字。实际上,计算机的准确度有限,因此算法将始终终止。

在二进制搜索算法中,当当前间隔的中点是正确的解决方案时,不是终止,而是当当前间隔的长度低于所需的精度时终止

由于每个步骤的间隔长度减半,如果您的启动间隔长度为 L 且您所需的精度为 e ,则算法会在log2后终止(< em> L / e )步骤。

当我们将这些算法组合在一起时,整体解决方案是

  1. 使用指数搜索
  2. 查找包含x *的区间[a,b]
  3. 使用二进制搜索
  4. 在[a,b]中找到x *的近似值

    正如我们所知,指数搜索[x,2x]返回的区间包含x *,整个算法采用log2(x * / x0)+ log2(x / e)步长,大约是log2(x * ²/(e x0)),
    因为x <= x * <= 2x

    回到你的问题

    既然你提到你想要一次修复一个数字,我猜你已经选择了 h ,这样最多需要10个步骤来达到一个x值,这样f (x)&gt; 0.否则,这或多或少是线性搜索,它比二进制搜索开始慢得多。

    查看问题答案的最简单方法是查看您为解决方案考虑的时间间隔的对数长度:

    • 使用二进制搜索,每次迭代搜索间隔长度减半,因此log2(L)变为log2(L / 2)= log2(L) - 1
    • 使用您的算法,搜索间隔长度减少到10%,最多10次迭代,因此在10步后log2(L)变为log2(L / 10)= log2(L) - 3.3219 ......
      如果我们看一个步骤,这可以归结为减少至少0.33219 ...,这意味着在最坏情况下你的算法的速度是二进制搜索速度的3倍,具有相同的精度。
      然而,这假设您总是需要采取10个步骤,因此如果我们假设数字随机均匀分布,那么我们每个数字平均只需要5个步骤,从而使您的算法成为可能比二元搜索慢〜30%