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. 。最終関数は、推測の最終反復を使用して、数学の平方根法から減算し、全体の差を返します。私はこれを正しくやっていますか?作業コードを提供していただければ、提案を添えていただければ幸いです。繰り返しますが、私は初心者なので、誤解や明らかな誤りについてはお詫び申し上げます。

4

5 に答える 5

9

ニュートン法の実装:

必要に応じて微調整を加えるのはかなり簡単です。試してみて、行き詰まったら教えてください。

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またはグーグルで十分な例を見つけることができますが、ループをカウントしている場合は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))
于 2012-10-11T23:37:26.057 に答える
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)
于 2013-03-08T02:13:40.480 に答える
2

平方根を計算するためのかなり異なる関数を次に示します。nが負でないことを前提としています。

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

このアルゴリズムはニュートンのアルゴリズムに似ていますが、同一ではありません。これは、1世紀(約2000年前)にエジプトのアレクサンドリアに住むヘロンというギリシャの数学者(彼の名前はヒーローと綴られることもあります)によって発明されました。ヘロンの漸化式はニュートンのものよりも単純です。x' = (x + n/x) / 2ニュートンが使用した場所でヘロンが使用されx' = x - (x^2 - n) / 2xました。

最初のテストはゼロの特殊なケースです。これがないと、(n < 1)テストによって無限ループが発生します。次の2つのテストでは、 nを範囲に正規化します1 < n <= 4範囲を小さくすると、 nの平方根の初期近似を簡単に計算できます。これはxの最初の計算で実行され、次に「ループを展開」して漸化式を一定回数繰り返すため、次のようになります。 2つの連続するループの差が大きすぎる場合は、テストと繰り返しの必要性。

ちなみに、ヘロンはかなり面白い仲間でした。平方根を計算する方法を発明したことに加えて、彼は実用的なジェットエンジン、コイン式の自動販売機、その他たくさんの素敵なものを作りました!

平方根の計算について詳しくは、私のブログをご覧ください。

于 2012-10-12T02:11:11.877 に答える
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)
于 2014-04-16T23:48:08.410 に答える
0

知っておく必要があるのは、数列の n 番目の項だけです。ライプニッツ級数から、これは ((-1)**n)/((2*n)+1) であることがわかります。初期条件ゼロですべての i についてこのシリーズを合計するだけで準備完了です。

def myPi(n):

pi=0
for i in range(0,n):
    pi=pi+((-1)**i)/((2*i)+1)
return 4*pi
print (myPi(10000))
于 2016-12-29T17:47:23.013 に答える