【问题标题】:Binary search root of function using recursion使用递归的函数的二进制搜索根
【发布时间】:2019-01-14 01:04:46
【问题描述】:

我正在尝试编写一个二分查找函数来查找函数fun 在区间[????????????????????,????????????] 中的根:

这是我所拥有的接近但缺少标记的东西:

def binarySearchIter(fun, start, end,  eps=1e-10):
    '''
    fun: funtion to fund the root
    start, end: the starting and ending of the interval
    eps: the machine-precision, should be a very small number like 1e-10

    return the root of fun between the interval [start, end]
    '''

    root = (start + end)/2
    print(root)

    answer=fun(root)

    if abs(answer) <= eps:
        print(root)
        return root
    elif answer - eps > 0:
        binarySearchIter(fun, start, root, eps=1e-10)
    else:
        binarySearchIter(fun, root, end,  eps=1e-10)

这是我用来测试的函数:

def f(x):
return x ** 2 - 2

当我运行:binarySearchIter(f, -3, 0, eps = 1e-10) 时,我希望得到答案:-1.4142135623842478,但是,root 会收敛到 -3,直到超时。

当我运行binarySearchIter(f, 0, 3, eps = 1e-10) 时,我得到了1.4142135623842478 的正确答案。

我显然遗漏了一些使函数中断的东西,具体取决于它是 (-3, 0) 还是 (3,0)。

感谢您的帮助。

【问题讨论】:

  • 二进制和布尔不是同义词
  • 你是 100% 正确的,我的错误,感谢 Azat 纠正我。
  • 我更喜欢 naxarark 但 azat 可以:)

标签: python python-3.x recursion binary-search


【解决方案1】:

您所看到的是您的函数仅适用于递增函数,这对于 03 之间的 x**2 - 2 是正确的,但不适用于递减函数,这对于您在 @ 之间的函数是正确的987654324@和0

有几种方法可以修复您的功能。一种方法是交换startend 的值,如果fun(start) &gt; fun(end)。换句话说,将您的root = (start + end)/2 行更改为三行

if fun(start) > fun(end):
    start, end = end, start
root = (start + end)/2

这确实会减慢您的日常工作,因此有更好的方法来完成您的日常工作。特别是,使用迭代而不是递归。与迭代相比,Python 的递归非常缓慢。

但是,您的功能并不可靠。您应该首先检查fun(start)fun(end) 是否有不同的符号。然后,您的例程将继续重新定义 startend,以便它们的图像继续具有相反的符号。如果符号相同,则在该区间内可能没有函数的根,并且您的例程肯定没有好的方法来决定继续搜索区间的哪一半。一种方法是在我已经插入的行之前添加这两行:

if fun(start) * fun(end) > 0:
    raise 'Endpoints in binarySearchIter should yield opposite signs.'

【讨论】:

    猜你喜欢
    • 2020-09-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-01-19
    • 2021-04-20
    • 2014-11-27
    • 1970-01-01
    相关资源
    最近更新 更多