用二分法定義平方根函數(Bisection method Square Root Python)


Python里面有內置(Built-in)的平方根函數:sqrt(),可以方便計算正數的平方根。那么,如果要自己定義一個sqrt函數,該怎么解決呢?

 

解決思路:

 1. 大於等於1的正數n的方根,范圍肯定在0~n之間;小於1的正數n的方根,范圍肯定在0~1之間

 2. 用二分法(Bisection method, Binary search)從中間開始找n的方根。

 3. 對於大於等於1的正數n,先假設n/2是n的方根,如果n/2的平方大於n,那么說明n的方根在0~n/2之間;如果n/2的平方小於n,說明n的方根在n/2~n之間。以此類推。。

 4. 對於小於1的正數n,先假設0.5是n的方根,方法同上

這樣做的好處是,每次都可以去掉一半可能的值。因此,搜索的范圍越來越小。

I------------------------I-------------------------I

0                          n/2                            n

 

舉例來說,如果是求8的平方根,那么先假設8的平方根是4;

4的平方是16,16大於8,因此8的平方根范圍縮小到0~4之間;

繼續假設8的平方根是2,2的平方是4,4小於8,因此8的平方根范圍縮小到2~4之間;

繼續假設8的平方根是3,3的平方是9,9大於8,因此8的平方根范圍縮小到2~3之間;

以此類推。。。

 

代碼如下:

def sqrt_bi(n):
    '''為了方便起見,先假設n為正數'''
    low=0   #設置下限為0
    high=max(n,1)   #設置上限為n和1之中的最大數,即:如果n>=1,那么上限為n;如果n<1,那么上限為1
    guess=(low+high)/2   #先從中間值開始猜
    count=1   #設置猜測次數起始值為1
    while abs(guess**2-n)>0.00000000000000000001 and count<100: #當猜測值的平方和n本身的差值無限接近誤差值時,循環才會停止;同時設置猜測次數不超過100次
        if guess**2<n:  #如果猜測值的平方小於n,那么將此設為下限
            low=guess
        else:           #如果猜測值的平方大於n,那么將此設為上限
            high=guess
        guess=(low+high)/2  #根據新的上下限,重新進行猜測
        count+=1    #猜測次數每次增加1
    return guess
* 這里,我將0.00000000000000000001設為epsilon(誤差值,epsilon為接近0值的浮點數)。epsilon越接近0,算出的方根值就越精確。

調用此函數試一下,同時與python自帶的sqrt函數進行對比:

print(sqrt_bi(8))
import math
print(math.sqrt(8))

運行結果如下:

2.82842712474619
2.8284271247461903

 

python自帶的sqrt函數比sqrt_bi函數還要更精確一些。

 

參考:麻省理工學院公開課:計算機科學及編程導論 (第5課)

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM