標籤:style blog color os io for ar 問題
1.基於問題規模的複雜度計算方法
在考慮時間效率的時候,面臨以下兩個問題:輸入規模以及步驟。
輸入規模受很多因素影響:參數大小、參數類型(數組、元組的存取小綠是不同的),而且不同操作步驟(加減、判斷)時間也不是相同的,為了方便計算,我們需要建立以下的假設:
假設從電腦取得任何變數的時間是相同的
假設基本操作時間恒定
接下來就可以考慮以下幾種情況:
最好情況:何種輸入會使得程式的已耗用時間最短?
最壞情況:何種輸入會使得程式的已耗用時間最長?
平均情況
如果考慮平均情況的話,就要去設想問題輸入規模的分布情況,這樣大大增加了計算的難度。因此,我們通常考慮的是最壞的情況,因為最壞情況能夠讓我們知道程式已耗用時間的上限,能夠避免意外的發生。
2. 執行個體分析 執行個體一:計算a的b次方方法一:常規方法
# 方法一:用常規方法計算a的b次方def exp1(a,b): ans = 1 #一次 while (b>0): #3b次 ans *= a b -= 1 return ans #一次
程式執行的步驟為:1 + 3b + 1 = 2 + 3b次
b = 300 , 執行次數:902;
b = 3000, 執行次數:90002;
b = 30000,執行次數,9000002;
可以發現,隨著b的增長,2和3的作用越來越小,因為單單b就可以體現出函數的增長的上限。因此我們引入了Big O的概念:
Big O:upper limit to growth of function as the input gets large.
大 O:當問題規模變大時候對應的解決方案的增長上限
因此,方法一的時間複雜度為O(b).
方法二:遞迴方法
#方法二:遞迴方法求a的b次方def exp2(a,b): if b == 1: #一次 return a else: return a*exp2(a,b-1) #2次,一次乘法,一次減法
首先我們假設時間為t(b),可以進行如下推導:
t(b)=3+t(b-1)
=3+3+t(b-2)
=...
=3k + t(b-k)
其中,b-k=1,代入,因為t(1)=2,所以,可得
t(b)=3b-1
因此,方法二的時間複雜度仍然為O(b)
方法三:根據b奇偶性的不同分別進行判斷
a**b:
b為偶數:(a*a)**(b/2),規模減半
b為奇數:a*(a**(b-1))
#8.3 分類法求平方根def exp3(a,b): if b == 1: return a if b%2 ==0: return exp3(a*a,b/2) else: return a*exp3(a,b-1)
可以簡單計算出時間複雜度:
b為偶數: t(b) = 5 + t(b/2)
b為奇數:t(b) = 5 + t(b-1) = 10 + t(b-1/2)
也就是說,沒經過兩輪,規模減半,所以時間複雜度為O(logb)
執行個體2:時間複雜度為O(n²)的例子
這個例子很簡單,不多說明
#8.4def g(n): x=0 for i in range(n): for j in range(m):x += 1 return x
執行個體3:漢羅塔問題
主要介紹如何從遞迴角度來考慮漢羅塔問題
解題思路:
設三個圓盤的名稱分別為為:fromstack(起始圓盤)、sparestack(空餘圓盤)、tostack(目的圓盤)
如果個數為1,直接從fromstack移動到tostack
如果個數為n:
- 將n-1個圓盤移動到sparestack
- 將第n個圓盤移動到tostack
- 然後將n-1個圓盤移動到tostack
代碼:
#8.4 用遞迴方法求解漢羅塔問題def Towers(size,fromStack,toStack,spareStack): if size == 1: print(‘Move disk from ‘,fromStack,‘to‘,toStack) else: Towers(size-1,fromStack,spareStack,toStack) Towers(1,fromStack,toStack,spareStack) Towers(size-1,spareStack,toStack,fromStack)
該演算法的時間複雜度為O(n²)