コンピュータ科学とPythonプログラミングの導論(3)いくつかの簡単な数値プログラム


基本概念
1.窮挙法 :推測と検証アルゴリズムの一種である.正しい答えが得られるか、すべての値を試し終わるまで、すべての可能性を列挙します.
#           
x = int(input('Enter an integer: '))
ans = 0
while ans**3 < abs(x):
    ans = ans + 1
if ans**3 != abs(x):
    print(x, 'is not a perfect cube')
else:
    if x < 0:
        ans = -ans
    print('Cube root of', x,'is', ans)

では、どのようなx値に対して、プログラムは正常に終了しますか?答えは「すべての整数」です. : 1.式ans**3の値は0から始まり、サイクルごとに徐々に大きくなります.2.この値がabs(x)に達したとき、サイクルは終了する.3.abs(x)の値は常に正であるため、ループ終了前の反復回数は必然的に限られる.ループを記述する場合は、適切な減算関数を使用します.この関数には、次の属性があります.
  • プログラム変数のセットを整数にマッピングすることができる.
  • ループに入ると、その値は負ではない.
  • 値≦0の場合、ループは終了する.
  • ループごとに値が減少する.

  • 2.forサイクル
    forサイクルではよく使われるrange() ですので、まずご紹介します.
  • range関数は、start、stop、stepの3つの整数パラメータを受け入れます.数列を生成します:start、start+step、start+2*stepなど.
  • stepが正数の場合、最後の要素はstopより小さい最大整数start+i*stepである.stepが負の場合、最後の要素はstopより大きい最小整数start+i*stepです.
  • 数列の数値は「オンデマンド発生」の原則で生成されるため、range(1000000)のような式でもメモリは少ない.
  • #           
    x = int(input('Enter an integer: '))
    for ans in range(0, abs(x)+1):
        if ans**3 >= abs(x):
            break
    if ans**3 != abs(x):
        print(x, 'is not a perfect cube')
    else:
        if x < 0:
            ans = -ans
        print('Cube root of', x,'is', ans)

    3.近似解と二分検索 被検索セットに答えが含まれている場合のみ有効な検索技術
    #           
    x = 25
    epsilon = 0.01
    step = epsilon**2
    numGuesses = 0
    ans = 0.0
    while abs(ans**2 - x) >= epsilon and ans <= x:
        ans += step
        numGuesses += 1
    print('numGuesses =', numGuesses)
    
    if abs(ans**2 - x) >= epsilon:
        print('Failed on square root of', x)
    else:
        print(ans, 'is close to square root of', x)
    
    クエリーの効率化
    x = 25
    epsilon = 0.01
    numGuesses = 0
    low = 0.0
    high = max(1.0, x)
    ans = (high + low)/2.0
    while abs(ans**2 - x) >= epsilon:
        print('low =', low, 'high =', high, 'ans =', ans)
        numGuesses += 1
        if ans**2 < x:
            low = ans
        else:
            high = ans
        ans = (high + low)/2.0
    print('numGuesses =', numGuesses)
    print(ans, 'is close to square root of', x)

    4.浮動小数点数について
    多くの場合、float の数値は実数のひとつでとても良い .しかし、「多くの場合」はすべての状況を意味するものではありません.この機能が失効すると不思議な結果を引き起こします.たとえば、次のコードを実行してみます.
    x = 0.0
    for i in range(10):
        x = x + 0.1
    if x == 1.0:
        print(x, '= 1.0')
    else:
        print(x, 'is not 1.0')
    #   
    0.9999999999999999 is not 1.0

    どうしてこんな結果になったのでしょうか.
  • これはバイナリと十進法の表現に関係しています(pythonでのバイナリの0.1は本当に十進法の0.1に等しいわけではありません).
  • Pythonで0.1と書いた10進数の1/10は?4桁の有効数字を使用すると、最良の表現は(0011,-101)、3/32、すなわち0.09375に等しい.5ビットの有効な2進数がある場合、0.1は25/256、すなわち0.09765625に等しい(11001,−1000)と表すことができる.では、浮動小数点数で0.1を正確に表すには何桁の有効な数字が必要ですか?無限位が必要です!2つの整数sigとexpは存在せず、sigを× 2-exp = 0.1.したがって、Python(または任意の言語)が浮動小数点数を何桁有効な数字で表しても、0.1の近似値しか表しません.
  • だから0.1を10回加算して本当に10に0.1を乗じた値ではない
  • 5.ニュートン・ラフソン法単変数多項式の値を求めるのに使えるが、単変数多項式とは何か.
    単一変数多項式または0、または有限数の非ゼロ単項式の和.各項は、定数(項の係数)に変数を乗じた非負の整数次数(ここでは2次数)からなる. :
    逐次迫るニュートンは,guessが多項式pのルートの近似値である場合,guess−p(guess)/p’(guess)はより良い近似値であり,p’はpの一次導関数であるという定理を実証した.
    #    .         
    #  x,  x**2-24 epsilon 0  
    epsilon = 0.01
    k = 24.0
    guess = k/2.0
    while abs(guess*guess - k) >= epsilon:
        guess = guess - (((guess**2) - k)/(2*guess))
    print('Square root of', k, 'is about', guess)

    プログラミング練習
    1.ユーザに整数を入力するようにプログラムを作成し、2つの整数rootとpwrを出力し、0 root**pwrユーザが した に しい.このような の が しない 、 のためにメッセージが されます.
    #   1
    r = int(input('input an integer'))
    root = 0
    i = 0
    for pwr in range(1, 7):
        result = -1
        while result < abs(r):
            root += 1
            result = root**pwr
        if result == abs(r):
            if r < 0:
                root = -root
            print('root:{},pwr:{}'.format(root, pwr))
            i += 1
        root = 0
    print('   {}     '.format(i))
    #   2
    x=int(input('Enter an integer: '))
    root=1
    pwr=1
    w=root**pwr
    i=0
    while w<abs(x) or root<=abs(x): 
        if pwr<6: 
            w=root**pwr
            if w==abs(x) and x<0:
                i+=1
                print('root','=',-root,'pwr','=',pwr)
            elif w==abs(x):
                i+=1
                print('root','=',root,'pwr','=',pwr)
            pwr+=1
        else:
            pwr=1
            root+=1
            w=root**pwr
    print('          {} '.format(i))

    2.sは の を む であり、カンマで られていると し、 えばs = '1.23, 2.4, 3.123'.プログラムを し、sのすべての の を します.
    #   1
    s = '1.23, 2.4, 3.123'
    sum = 0.0
    for i in map(lambda i: float(i), s.split(',')):
        sum += i
    print(sum)
    #   2
    s = '1.23, 2.4, 3.123'
    a=s.split(',')
    t=0
    for i in a:
        t=t+float(i)
    print(t)

    3. x=25がx=-25に き えられた 、コードはどのように されますか?
             
    #    while   ,x     。        (abs(ans**2 - x) >= epsilon)    ,         。
    x = -25
    epsilon = 0.01
    numGuesses = 0
    low = 0.0
    high = max(1.0, x)
    ans = (high + low)/2.0
    while abs(ans**2 - x) >= epsilon: #          
        print('low =', low, 'high =', high, 'ans =', ans)
        numGuesses += 1
        if ans**2 < x:
            low = ans
        else:
            high = ans
        ans = (high + low)/2.0
    print('numGuesses =', numGuesses)
    print(ans, 'is close to square root of', x)

    4. 3-4のコードをどのように して、1つの の を めることができますか?この は でも でもよい.(ヒント:lowを して、 えが にあることを します.)
    x = -30
    epsilon = 0.01
    numGuesses = 0
    x_abs = abs(x)  #     
    low = 0.0
    high = max(1.0, x_abs)
    ans = (high + low) / 2.0
    while abs(ans**3 - x_abs) >= epsilon:
        numGuesses += 1
        if ans**3 < x_abs:
            low = ans
        else:
            high = ans
        ans = (high + low) / 2.0
    print('numGuesses =', numGuesses)
    if x < 0:
        print(-ans, 'is close to square root of', x)
    else:
        print(ans, 'is close to square root of', x)

    5.2 10011は10 のどの に しいですか.
    19
    #   1     
    #   2     
    int('10011',base=2)

    6.ニュートンでラフソン の にはいくつかのコードを し, を めるために いられる を した.このコードに づいてプログラムを し、ニュートンを する.ラフソン と ルックアップ の .
    #    .         
    #  x,  x**2-24 epsilon 0  
    epsilon = 0.01
    k = 24.0
    guess = k/2.0
    a=0
    while abs(guess*guess - k) >= epsilon:
        guess = guess - (((guess**2) - k)/(2*guess))
        a+=1
    print('Square root of', k, 'is about', guess)
    print('       ={}'.format(a))
    
    #            
    #  x,  x**2-24 epsilon 0  
    x = 24.0
    epsilon = 0.01
    numGuesses = 0
    low = 0.0
    high = max(1.0, x)
    ans = (high + low)/2.0
    b=0
    while abs(ans**2 - x) >= epsilon:
        numGuesses += 1
        if ans**2 < x:
            low = ans
        else:
            high = ans
        ans = (high + low)/2.0
    print(ans, 'is close to square root of', x)
    print('        ={}'.format(numGuesses))
    Square root of 24.0 is about 4.8989887432139305
           =4
    4.8984375 is close to square root of 24.0
            =9