了解使用Bisection方法查找解决方案的迭代次数

时间:2017-03-01 22:43:23

标签: python algorithm python-3.x for-loop bisection

我被要求使用Bisection方法找到方程的根,并且只有{3}}循环使用Python 3. This线程显示如何使用该方法,但没有说明数字的解释在for

举个例子,我有函数

  

f(x)= x 2 - 2 * x - 3

我希望找到它的负根,从区间[-4,1]开始。

我设法用range()循环编写函数,但我不明白我应该使用哪个范围,或者如何提出它。

这是我的代码,解决了这个问题:

for

c = -1(找到负根),f(c)= 0确认程序有效,i = 52表示在52次“尝试”二分后,它找到了正确答案。

我在... a = -4 b = 1 c = (a + b)/2 for i in range(1000): if f(c) == 0: break if f(a) * f(c) < 0: b = c elif f(a) * f(c) > 0: a = c c = (a + b) / 2 return c, f(c), i 中放了一个非常大的数字以确保找到了根,但为什么它只需要52次迭代?

另外,如果我的间隔变为[-2,1],我需要53次尝试。 为什么会这样?

2 个答案:

答案 0 :(得分:1)

每次迭代,您将搜索间隔减半。在每次迭代中,您检查f(c)(中点的功能值)是否为0,在计算机浮点表示的精度范围内。

如果你选择区间[-101,99],你只需要在1次迭代中得到解,就像你点击c = -1那样。只要程序足够接近评估结果为0.000000

的实际根,程序就会停止

你开始的宽度范围是5.什么是5除以2,52倍?实现中浮点数的准确度是多少?我敢打赌你接近两个花车之间的最小差异。

如果你真的想看到这个,请在​​循环中添加一个简单的行,就在顶部:

print a, b, c, f(c)

这将显示找到根目录的进度。

打印语句是一种低技术,有效的跟踪程序的方法。

评论回复

好点:我还没有足够强硬地说出具体案例。

你完成了52次迭代,因为这是程序在正确值上“绊倒”所花费的数量。当你改变并在53次迭代中进行更小范围时...简单的方法是说你第一次有点幸运。正如我 指出的那样,如果你开始使用-1作为其中点的东西,例如[-101,99],那么你将只完成一个迭代,尽管有更大的间隔。

答案 1 :(得分:1)

如果您在循环中print([a, b]),则可以看到范围演变:

[-4, 1]
[-1.5, 1]
[-1.5, -0.25]
[-1.5, -0.875]
[-1.1875, -0.875]
[-1.03125, -0.875]
...
...
...
[-1.0000000000000284, -0.9999999999999929]
[-1.0000000000000107, -0.9999999999999929]
[-1.0000000000000018, -0.9999999999999929]
[-1.0000000000000018, -0.9999999999999973]
[-1.0000000000000018, -0.9999999999999996]
[-1.0000000000000007, -0.9999999999999996]

计算出的平均值-1.0000000000000007和-0.9999999999999996正好为-1。为什么?因为你已经达到浮标代表的极限。以下是所涉及的确切值:

>>> '%.60f' % -1.0000000000000007
'-1.000000000000000666133814775093924254179000854492187500000000'

>>> '%.60f' % -0.9999999999999996
'-0.999999999999999555910790149937383830547332763671875000000000'

>>> '%.60f' % (-1.0000000000000007 + -0.9999999999999996)
'-2.000000000000000000000000000000000000000000000000000000000000'

>>> '%.60f' % ((-1.0000000000000007 + -0.9999999999999996) / 2)
'-1.000000000000000000000000000000000000000000000000000000000000'

浮点存储52 bits of fraction,意思是前导1位后的52位。意味着你失去了比你的价值约1/2 52 小的东西。经过52个步骤后,您的初始5号范围大约为5/2 52 。这是你的价值-1的1/2 52 。因此,在那里,由于不精确,你很有可能偶然发现-1。

可能需要两个或三个步骤,因为5/2 52 仍然比1/2 52 大一点。你那里很幸运。使用您的其他初始范围[-2, 1],您就不那么幸运了。在达到-1之前,你的范围会缩小到[-1.0000000000000002, -0.9999999999999999]

如果您从[-4000000, 1]开始,那么您需要72个步骤。它的步骤多了20步,因为初始范围是一百万倍,大约是2 20

另一种情况:如果您使用函数x**2 - 1000000和初始范围[999.3, 1000.3],则需要41步。为什么?最终值(即根)是1000,初始范围是1。那是1/1000,所以约1/2 10 。所以要达到1/2 52 ,你只需要大约42个二等分。