一、漸進時間複雜度
基本操作的數量往往可以寫成關於「輸入規模」的表示式,保留最大項並忽略係數後的簡單表示式稱為演算法的漸進複雜度,用於衡量基本運算元隨規模的增長情況。
例如:設輸入規模為n時加法操作的次數為t(n),t(n) = n(n+1)(n+2)/6。
當n很大時,平方項和一次項對整個多項式的影響不大,可以用乙個記號來表示:t(n) = θ(n3),或者說t(n)和n3同階。
同階指「增長情況相同」。
(漸進時間複雜度忽略了很多因素,因而分析結果只能作為參考,並不是精確的。儘管如此,如果抓住了最主要的運算量所在,演算法分析的結果常常十分有用。)
二、上界分析
另一種推導時間漸進複雜度的方法:
下面是求最大連續和的**
int f(int p, intn) }
}return
ans;
}
3重迴圈最壞情況下都需要n次,因此總運算次數不超過n3。上界的記號為t(n)=o(n3)。
在演算法設計中,常常不進行精確分析,而是假定各種最壞的情況同時取到,得到上界。在很多情況下,這個上界和實際情況同階(稱為「緊」的上界),但也有可能會因為分析方法不夠好,得到「松」的上界。
松的上界也是正確的上界,但可能讓人過高的估計程式執行的實際時間(從而不敢編寫程式),而即使上界是緊的,過大或過小的最高項係數同樣可能引起錯誤的估計。換句話說,演算法分析不是萬能,要謹慎對待分析結果。如果預感到上界不緊、係數過大或者過小,最好還是程式設計實踐。
ps.最大連續和的一種優化方法:
int f(int p, int s, intn)
for(int i = 1; i <= n; i ++)
}return
ans;
}int
main()
cout
<< f(p, s, n)
}
遞推思想
用類似的方法可得出t(n)=o(n2)
三、分治
根據最大連續和演算法的進一步優化,分析分治思想的效能。
分治演算法一般分為以下3個步驟:
劃分問題:把問題的例項劃分成子問題。
遞迴求解:遞迴解決子問題。
合併問題:合併子問題的解得到原問題的解。
最大連續和的分治演算法:
1、把序列分成元素個數盡量相等的兩半;2、分別求出完全位於左半或者完全位於右半的最佳序列;3、求出起點位於左半、終點位於右半的最大連續和序列,並和子問題的最優解比較。
int f(int a, int x, int y)//返回在[x,y)中的最大連續和
int mid = x + (y - x) / 2, ans =a[x];
ans =max(ans, f(a, x, mid));
ans =max(ans, f(a, mid, y));
int l = a[mid - 1],r =a[mid];
for(int i = x; i < mid; i ++)
l =max(l, sum);
}for(int i = mid; i < y; i ++)
r =max(r, sum);
}ans = max(ans, l +r);
return
ans;
}
是否可以像前面那樣,得到tot(基本運算元)的數學表示式呢?注意求和技巧已經不再適應,需要用遞迴的思路進行分析:設序列長度為n的tot值為t(n),則t(n)=2t(n/2)+n,t(1)=1。其中2t(n/2)
是2次長度為n/2的遞迴呼叫,最後的n是合併的時間。
解方程得t(n)=θ(nlogn)。nlogn增長很慢,比如,當n擴大2倍時,執行時間的擴大倍數只是略大於2。
遞迴方程t(n)=2t(n/2)+θ(n)
,t(1)=1的解為t(n)=θ(nlogn)。可以用解答樹證明這個理論,也可以作為乙個重要結論記下來。
該方法的2個細節:
1、左閉右開的「陣列分割」。使得處理自然。
2、(x+y)/2和x+(y-x)/2。數學上等價,在計算機中,前者是朝零取整,後者是朝區間起點取整。
四、正確對待演算法分析結果
假設機器速度是每秒108次基本運算,運算量為n3、n2、nlog2n、n、n!(排列)、2n(子集列舉)的演算法,在1s之內能解決最大問題規模n,如表所示:
運算量 n!
2nn3n2
nlog2n n
最大規模 11 26 464 10000 4.5*106 108
速度擴大兩倍後 11 27 584 14142 8.6*106 2*108
n!和2n不僅解決的問題規模非常小,而且增長緩慢;nlog2n、n
不僅解決問題的規模大,而且增長快。漸進時間複雜為多項式的演算法稱為多項式時間演算法,也稱有效演算法。像n!和2n 這樣低效的演算法稱為指數時間演算法。
需要注意的是,分析結果在趨勢上能反映演算法的效率,但有2個不確定性:一是公式本身的不精確性(係數、非主流操作的影響);二是對程式實現細節與計算機硬體的依賴性。在不少情況下,演算法實際能解決的問題和表所示有著較大差異。
但是還是有一定借鑑意義的,例如n<=8,n!的演算法已經足夠了,n<=20,需要用到2n的演算法,n<=300,必須用至少n3的多項式時間演算法。
演算法分析與優化
同一問題可用不同演算法解決,而乙個演算法的質量優劣將影響到演算法乃至程式的效率.演算法分析的目的在於選擇合適演算法和改進演算法.乙個演算法的評價主要從時間複雜度和空間複雜度來考慮.1 時間複雜度 1 時間頻度 乙個演算法執行所耗費的時間,從理論上是不能算出來的,必須上機執行測試才能知道。但不可能也沒...
演算法優化策略
下面是紫書上講的常用演算法設計策略和優化策略 拆分出的狀態必須滿足最優子結構性質和無後效性 當前階段以前的狀態不會影響以後的狀態,只與當前階段有關 動歸的目的是避免重疊子問題。遞推和遞迴 記憶化搜尋 是實現動歸的手段。只要滿足 1.狀態設計不重不漏 2.轉移方程正確 3.能順利統計答案,那麼這個dp...
演算法設計與分析課堂筆記(3)搜尋優化策略
best first法 分支界限法 a 法總結 我們最常見的bfs和dfs是搜尋演算法的基礎,bfs是以廣度方向不斷延伸邊界進行擴充套件,而dfs則是沿深度方向直指最終結果。二者分別有著特定的生長規律,使得遍歷能夠有序的進行,但是在延伸時還是缺少一些啟發式的選擇。二者因此也可以被認作是一種暴力窮舉,...