问题:我想搜索x_0
的实数f(x_0)=0
。我们只知道f
是单调递增的,无衍生的,x_0
是真正的积极,但不是非常大,因此程序不会终止。
当我没有参加算法课程时,我为此编写了一个程序,让我们称之为alternative search
。
要做的是初始化步长h
并从左侧开始增量。如果f(x_0)>0
,则退后一步,从现在开始按h/10
递增。换句话说,一次修复x_0
一个数字,并在步长非常小时终止。
这种方法与二分法搜索(或有人称之为二分法)相比如何?
我的直觉告诉我,每次alternative search
解决问题的十分之一,与一半相比,速度会慢一些。应该是对的,是吗?
答案 0 :(得分:2)
如果您只对即时问题的答案感兴趣,请跳至第二部分 在第一部分中,我将解释如何在您的案例中实际使用二进制搜索。
首先,这个问题无法单独通过二分搜索来解决,因为你需要一个区间[a,b],其中你的解x *与f(x *)= 0所在。 例如,可以使用指数搜索算法找到这样的间隔:
这样,你的算法在最多log2(x * / x0)步骤之后终止,其值为x,我们知道f(x)< 0和f(2x)>因此,我们可以在二进制搜索中使用这个区间[x,2x]。
另外,如果你的解x *是一个实数,二进制搜索一般不能给你精确的解,只有一个具有任意精度的近似值(更具体地说是一个区间),作为一个实数可以有无数的数字。实际上,计算机的准确度有限,因此算法将始终终止。
在二进制搜索算法中,当当前间隔的中点是正确的解决方案时,不是终止,而是当当前间隔的长度低于所需的精度时终止
由于每个步骤的间隔长度减半,如果您的启动间隔长度为 L 且您所需的精度为 e ,则算法会在log2后终止(< em> L / e )步骤。
当我们将这些算法组合在一起时,整体解决方案是
正如我们所知,指数搜索[x,2x]返回的区间包含x *,整个算法采用log2(x * / x0)+ log2(x / e)步长,大约是log2(x * ²/(e x0)),
因为x <= x * <= 2x
既然你提到你想要一次修复一个数字,我猜你已经选择了 h ,这样最多需要10个步骤来达到一个x值,这样f (x)&gt; 0.否则,这或多或少是线性搜索,它比二进制搜索开始慢得多。
查看问题答案的最简单方法是查看您为解决方案考虑的时间间隔的对数长度: