3

Heron 的方法生成一个数字序列,这些数字代表√n的越来越好的近似值。序列中的第一个数字是任意猜测;序列中的每个其他数字都是使用公式从前一个数字prev获得的:

    (1/2)*(prev+n/prev)

我应该编写一个heron()将两个数字作为输入的函数:nerror该函数应该从1.0的初始猜测开始,然后重复生成更好的近似值,直到逐次逼近之间的差值(更准确地说,差值的绝对值)最多为error

    usage:
    >>> heron(4.0, 0.5)
    2.05
    >>> heron(4.0, 0.1)
    2.000609756097561

这有点棘手,但我需要跟踪四个变量:

    # n, error, prev and current

我还需要一个带有条件的while循环

    ((current - prev) > error):

while循环的一般规则是:

    # old current goes into new prev

所以这就是我到目前为止所得到的,这并不多,因为一开始我不知道如何在while循环下合并“if”语句。

def heron(n, error):
    guess = 1
    current = 1
    prev = 0
    while (current - prev) > error:
        previous==1/2*(guess+n/guess):
           print (previous) # just a simple print statement
                            # in order to see what i have so far

有人可以给我一些正确方向的指示吗?

谢谢你

4

5 回答 5

4

如果您不想使用生成器,那么最简单的方法是:

def heron(n, error):
    prev, new = 1.0, 0.5 * (1 + n)
    while abs(new - prev) > error:
        prev, new = new, 0.5 * (new + n/new)
    return new

您还可以生成一个“无限”的苍鹭数序列:

def heron(n):
    prev = 1.0
    yield prev, float('inf')
    while True:
        new = 0.5 * (prev + n/prev)
        error = new - prev
        yield new, error
        prev = new

现在您可以打印任意数量的数字,例如:

list(islice(heron(2), 3))     # First 3 numbers and associated errors

只要误差大于0.01就生成:

list(takewhile(lambda x:x[1] > 0.01, heron(2)))
于 2013-05-17T23:50:06.973 回答
1

只是以@elyase 的答案为基础,以下是您如何从他们提供的苍鹭数生成器中获得任意精度的平方根。(生成器只给出苍鹭序列中的下一个数字)

def heron(n): ### posted by elyase
    a = 1.0
    yield a
    while True:
        a = 0.5 * (a + n/a)
        yield a

def sqrt_heron(n, err):
    g = heron(n)
    prev = g.next()
    current = g.next()
    while( (prev - current) > err):
        prev = current
        current = g.next()
        print current, prev
    return current

print sqrt_heron(169.0,0.1)

除了 python 语法之外,可能会让您感到困惑的是,您需要从最初的猜测中计算出两个猜测才能开始,然后比较这两个猜测的距离。(prev - current) > errwhile 条件不应该是(current - prev) > err因为我们期望之前的猜测更接近平方(因此更大)而不是当前的猜测应该更接近平方根。由于初始猜测可能是任何正数,我们需要从中计算两次迭代,以确保current小于prev

于 2013-05-18T00:15:15.533 回答
0

在我写这篇文章时,其他答案是使用 Python 生成器函数。我喜欢生成器,但对于这个简单的问题来说,它们太过分了。下面是简单while循环的解决方案。

代码下方的注释。 heron0()是你要求的;heron()是我建议的版本。

def heron0(n, error):
    guess = 1.0
    prev = 0.0
    while (guess - prev) > error:
        prev = guess
        guess = 0.5*(guess+n/guess)
        print("DEBUG: New guess: %f" % guess)
    return guess

def _close_enough(guess, n, allowed_error):
    low = n - allowed_error
    high = n + allowed_error
    return low <= guess**2 <= high

def heron(n, allowed_error):
    guess = 1.0
    while not _close_enough(guess, n, allowed_error):
        guess = 0.5*(guess+n/guess)
        print("DEBUG: New guess: %f" % guess)
    return guess

print("Result: %f" % heron0(4, 1e-6))
print("Result: %f" % heron(4, 1e-6))

注释:

  • 你真的不需要两者guesscurrent。您可以使用guess来保存当前的猜测。

  • 我不知道您为什么要在循环中添加if语句。while首先,这很容易:您只需将其放入,然后缩进if. 其次,这个问题不需要它。

  • 检测是否guess接近prev. 但我认为对于数值准确性,最好直接测试平方根guess实际上有多好。因此,将 的值平方guess并查看它是否接近n。看看在 Python 中如何同时测试一个值是否大于或等于一个较低的值并且小于或等于一个较高的值是合法的。(另一种检查方法 abs(n - guess**2) <= allowed_error:)

  • 在 Python 2.x 中,如果将整数除以整数,您可能会得到整数结果。从而1/2很可能会有一个结果0。有几种方法可以解决这个问题,或者您可以在 Python 3.x 中运行您的程序,以保证1/2返回0.5,但是将您的起始值guess设置为浮点数很简单。

于 2013-05-18T00:46:43.823 回答
0

我认为这符合您的要求(注意:我用 python 2.7.10 编写了它):它不假设猜测为 1,它需要 'num' 和 'tolerance' 作为 'n' 和 'error' 的参数。此外,它不使用变量“prev”和“current”或 while 循环 - 这些是您的要求的一部分,还是您对解决方案的想法?

def heron(num, guess, tolerance):
    if guess**2 != num:
        ##print "guess =", guess
        if abs(float(num) - float(guess)**2) > float(tolerance):
            avg_guess = 0.5 * (float(guess) + (float(num) / float(guess)))
            return heron(num, avg_guess, tolerance)
        print "Given your tolerance, this is Heron's best guess:", guess
    else:
        print guess, "is correct!"

如果您想查看猜测的进程,请取消注释 print cmd。

于 2016-04-04T03:22:27.383 回答
0

我正在处理同样的问题,但没有多少工具可以解决它,因为我对 Python 的了解非常有限。
我想出了这个不是很优雅也不是很高级的解决方案,但是它使用 Heron 的算法解决了这个问题。只想在这里分享:

print("Please enter a positive integer 'x' to find its square root.")
x = int(input("x ="))
g = int(input("What's your best guess: "))
results = [g]
if g * g == x:
    print("Good guess! The square root of", x, "is", g)
else:
    g = (g + (x / g)) / 2
    results.append(g)
    while results[-1] != results[-2]:
        g = (g + (x / g)) / 2
        results.append(g)
    else:
        print(results)
        print("Not quite. The square root of", x, "is", results[-1])
于 2020-06-05T05:01:00.417 回答