【问题标题】:infinite loop in appropriate solution适当解决方案中的无限循环
【发布时间】:2017-10-04 19:04:24
【问题描述】:

我不知道为什么下面的代码有无限循环。谢谢你告诉我和回答!

cube = 25
epision = 0.01
guess = 0
increment = 0.01
while abs(guess**3 - cube) >= epision:
    guess += increment
if abs(guess**3 - cube) >= epision:
    print("Failed on cube root of", cube)
else:
    print (guess, 'is close to the cube root of',cube)

【问题讨论】:

  • if 永远不会是真的,因为如果是的话,循环会重复。
  • 你为什么希望循环永远结束?
  • 考虑guess**3 - cube。猜测从 0 开始,所以它是 -25。然后它变成 1,它是 -24。然后它变成 2,它是 -17。然后它变成 3,它是 2。从​​那时起,差异总是正的,并且随着每次迭代而变得更大。问题在于,将 1 加到guess 会开始将其从期望值移得更远,而不是更近。这不是真正的 Python 问题,而是算法问题。

标签: python loops


【解决方案1】:

问题在于,即使在最接近的情况下,guess**3cube 之间的绝对差异仍然是 0.10291200000046885,因此大于 epsilon

要修复它,您可以:

  • 使用更大的epsilon 或更小的increment
  • 或将绝对差值与上一次迭代中的差值进行比较,break 再次升起时的星星
  • 或者只是检查是否guess**3 > cube,因为无论如何你都是从0 进行测试而不是做例如二分查找

或者,实际上使用 binary search;这是一个更好的算法,收敛速度更快,并且对于(几乎)任意小的 epsilon,实现起来并不难:

lower, upper = 0, cube # cube root has to be between these two numbers
while abs(guess**3 - cube) >= epision:
    if guess**3 > cube:
        guess, upper = (guess + lower) / 2, guess
    else:
        guess, lower = (guess + upper) / 2, guess

【讨论】:

    【解决方案2】:

    25 的立方根大约是2.92402

    guess = 2.92guess ** 3 = 24.897,所以abs(guess ** 3 - cube) == 0.103,不小于epsilon。所以你将0.01 添加到guess

    guess = 2.93guess ** 3 = 25.154,所以abs(guess ** 3 - cube) = 0.154,同样不小于epsilon

    随着您不断将0.01 添加到guess,您将离得更远,因此循环无限继续。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-01-27
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多