2012-10-11 40 views
2

我正在使用Python中的牛頓猜測和檢查方法來完成一個近似數字的平方根的數學問題。用戶應該輸入一個數字,初始猜測數字,以及他們想要在返回之前檢查他們的答案的次數。爲了讓事情變得更容易,並且瞭解Python(幾個月前我纔剛剛開始學習這門語言),我將它分解爲一些較小的函數;現在的問題是,我無法調用每個函數並傳遞數字。使用牛頓的方法找到平方根(錯誤!)

這裏是我的代碼,與意見,以幫助(每個功能在使用順序排列):

# This program approximates the square root of a number (entered by the user) 
# using Newton's method (guess-and-check). I started with one long function, 
# but after research, have attempted to apply smaller functions on top of each 
# other. 
# * NEED TO: call functions properly; implement a counting loop so the 
# goodGuess function can only be accessed the certain # of times the user 
# specifies. Even if the - .001 range isn't reached, it should return. 

# sqrtNewt is basically the main, which initiates user input. 

def sqrtNewt(): 
    # c equals a running count initiated at the beginning of the program, to 
    # use variable count. 
    print("This will approximate the square root of a number, using a guess-and-check process.") 
    x = eval(input("Please type in a positive number to find the square root of: ")) 
    guess = eval(input("Please type in a guess for the square root of the number you entered: ")) 
    count = eval(input("Please enter how many times would you like this program to improve your initial guess: ")) 
    avg = average(guess, x) 
    g, avg = improveG(guess, x) 
    final = goodGuess(avg, x) 
    guess = square_root(guess, x, count) 
    compare(guess, x) 


# Average function is called; is the first step that gives an initial average, 
# which implements through smaller layers of simple functions stacked on each 
# other. 
def average(guess, x) : 
    return ((guess + x)/2) 

# An improvement function which builds upon the original average function. 
def improveG(guess, x) : 
    return average(guess, x/guess) 

# A function which determines if the difference between guess X guess minus the 
# original number results in an absolute vale less than 0.001. Not taking 
# absolute values (like if guess times guess was greater than x) might result 
# in errors 
from math import * 
def goodGuess(avg, x) : 
    num = abs(avg * avg - x) 
    return (num < 0.001) 

# A function that, if not satisfied, continues to "tap" other functions for 
# better guess outputs. i.e. as long as the guess is not good enough, keep 
# improving the guess. 
def square_root(guess, x, count) : 
    while(not goodGuess(avg, x)): 
     c = 0 
     c = c + 1 
     if (c < count): 
      guess = improveG(guess, x) 
     elif (c == count): 
      return guess 
     else : 
      pass 

# Function is used to check the difference between guess and the sqrt method 
# applied to the user input. 
import math 
def compare(guess, x): 
    diff = math.sqrt(x) - guess 
    print("The following is the difference between the approximation") 
    print("and the Math.sqrt method, not rounded:", diff) 

sqrtNewt() 

目前,我得到這個錯誤:g, avg = improveG(guess, x) TypeError: 'float' object is not iterable. 最終的功能使用的猜測最終迭代從數學平方根法減去,並返回整體差異。 我是否做對了?工作代碼將不勝感激,並提供建議,如果你可以提供。再次,我是一個新手,所以我對錯誤觀念或盲目的明顯錯誤表示歉意。

+1

有你看着http://radiantbytes.com/books/python-latex/src/chap9.html - 這一切都沒有:) – root

回答

7

實現牛頓方法:

它應該很容易在需要時小的調整要添加到它。嘗試,並告訴我們什麼時候卡住了。

from math import * 
def average(a, b): 
    return (a + b)/2.0 
def improve(guess, x): 
    return average(guess, x/guess) 
def good_enough(guess, x): 
    d = abs(guess*guess - x) 
    return (d < 0.001) 
def square_root(guess, x): 
    while(not good_enough(guess, x)): 
     guess = improve(guess, x) 
    return guess 
def my_sqrt(x): 
    r = square_root(1, x) 
    return r 

>>> my_sqrt(16) 
4.0000006366929393 

注意:你會發現如何在SO或谷歌搜索在這裏使用原始輸入足夠exaples,但是,如果你指望環路,c=0必須是外循環,否則你會被卡在無限循環。

Quiqk和骯髒的,大量的方法來改善:

from math import * 
def average(a, b): 
    return (a + b)/2.0 
def improve(guess, x): 
    return average(guess, x/guess) 
def square_root(guess, x, c): 
    guesscount=0 
    while guesscount < c : 
     guesscount+=1 
     guess = improve(guess, x) 
    return guess 
def my_sqrt(x,c): 
    r = square_root(1, x, c) 
    return r 

number=int(raw_input('Enter a positive number')) 
i_guess=int(raw_input('Enter an initial guess')) 
times=int(raw_input('How many times would you like this program to improve your initial guess:'))  
answer=my_sqrt(number,times) 

print 'sqrt is approximately ' + str(answer) 
print 'difference between your guess and sqrt is ' + str(abs(i_guess-answer)) 
+0

+1 - 很好做。我不認爲這個網站會給你這樣的問題帶來好處。 8) – duffymo

+0

@ duffymo - 就這樣,是的:) – root

+0

謝謝!我應該說我正在使用Python ver 3.30,所以我做了相應的更改。我想我也可以從Math.sqrt返回的數字中減去猜測。再次,這是非常有幫助的;真的很感激這個! – user1739537

2

這裏是一個完全不同的函數來計算平方根;它假定ñ非負:

def mySqrt(n): 
    if (n == 0): 
     return 0 
    if (n < 1): 
     return mySqrt(n * 4)/2 
    if (4 <= n): 
     return mySqrt(n/4) * 2 
    x = (n + 1.0)/2.0 
    x = (x + n/x)/2.0 
    x = (x + n/x)/2.0 
    x = (x + n/x)/2.0 
    x = (x + n/x)/2.0 
    x = (x + n/x)/2.0 
    return x 

這種算法類似於牛頓的,但不完全相同。它是在一世紀(約二千年前),由一位名叫Heron的希臘數學家發明的(他的名字有時拼寫英雄)住在埃及亞歷山大港。 Heron的遞推公式比牛頓簡單,蒼鷺使用x' = (x + n/x)/2其中牛頓使用x' = x - (x^2 - n)/2x

第一個測試是零的一個特例;沒有它,(n < 1)測試會導致無限循環。接下來的兩個測試將n標準化爲範圍1 < n <= 4;使範圍小意味着我們可以很容易地計算初始近似值的平方根的Ñ,其在的X第一計算完成,然後「展開循環」和迭代遞推方程的固定數量次,因此消除了對兩次連續循環之間的差異過大的測試和循環的需要。

順便說一句,Heron是一個非常有趣的傢伙。除了發明了計算平方根的方法,他建立了一個工作的噴氣發動機,投幣式自動售貨機,和許多其他奇妙的東西!

你可以閱讀更多關於my blog計算平方根。

+0

謝謝!將我的代碼的評論加入;相當有幫助。 – user1739537

7

選擇的答案有點複雜...沒有不尊重OP​​。

對於誰曾谷歌這在將來任何人,這是我的解決方案:

def check(x, guess): 
    return (abs(guess*guess - x) < 0.001) 

def newton(x, guess): 
    while not check(x, guess): 
     guess = (guess + (x/guess))/2.0 
    return guess 

print newton(16, 1) 
0

它不應該有那麼複雜,我寫這件事

def squareroot(n,x): 
final = (0.5*(x+(n/x))) 
print (final) 
for i in range(0,10): 
    final = (0.5*(final+(n/final))) 
    print (final) 

,或者你可以將其更改爲像這樣

n = float(input('What number would you like to squareroot?')) 
x = float(input('Estimate your answer')) 
final = (0.5*(x+(n/x))) 
print (final) 
for i in range(0,10): 
    final = (0.5*(final+(n/final))) 
    print (final) 
0

所有你需要知道的是序列中的第n項。從萊布尼茲系列中,我們知道這是((-1)** n)/((2 * n)+1)。對於所有我來說,只需對這個系列進行總結,初始條件爲零,然後設置好。

def myPi(n): 

pi=0 
for i in range(0,n): 
    pi=pi+((-1)**i)/((2*i)+1) 
return 4*pi 
print (myPi(10000))