算法分析與設計復習
算法分析與設計復習
2016年初,研一上學期期末考試前,復習並總結算法分析與設計科目的內容。復習過程參照《算法導論》中文第2版,同時參照PPT,章節划分根據PPT內容
概要:
第一章 概述
第二章 插入排序&分治策略
第三章 復雜度分析
第四章 堆與堆排序
第五章 快速排序
第六章 線性時間排序
第七章 中位數和順序統計
第八章 動態規划(DP)
第九章 貪心算法
第十章 最短路徑算法
第十一章 回溯法&分支限界法
第十二章 NP問題與一些概念
第一章 概述
-
算法的應用范圍
算法在諸如生物等諸多領域有其應用
-
算法的意義
算法在很多情況下讓不可能完成的事情變成了可能,讓處理的很慢的過程變快。
-
一個鋪墊
一串不全為負的數,怎么取能拿到一段和最大的子串(最大子段和)
第二章 插入排序&分治策略
-
插入排序
- 掌握插入排序的方法
-
循環不變式的證明
初始化:
保持:
終止:
-
逐步計算插入排序的時間復雜度:
結論(基於RAM模型下):
Best Case:O(n)
Worst Case:O(n^2)
-
分治策略
-
概述:
大問題拆成多個小問題,分別計算每個小問題的解最后把多個小問題合成原問題的解
-
-
MERGE Sort
- 掌握歸並排序的方法
-
分析歸並排序
- 通過遞歸式分析
- Best case:nlgn
- Worst case:nlgn
-
課后習題總結
- 推演一個插入排序的過程
- 循環不變式證明線性查找的正確性
- 對給定的時間復雜度表達式寫出Θ
- 推演一個MERGE Sort
- 算法設計題:可以看*
第三章 復雜度分析
-
時間復雜度分析
-
歸並排序分析
-
代換法(證明手段)
- 做一個好的猜測
- 假設這個界對某一個范圍內成立
- 帶入得出結論
- 數學歸納法證明結論正確
-
遞歸樹
- 時間復雜度的表達式是每一層拆分開銷之和加上最底層每一個未知的開銷。
-
主定理(必會)
- 形如:T(n)=aT(n/b)+f(n)
-
三種情況:
- 若存在ε>0,有f(n)=O(n^(log b(a)-ε)),則T(n)=Θ(n^(log b(a)))
- 若f(n)=Θ(n^(log b(a))),T(n)=Θ(n^(log b(a))lg(n))
- 若對某ε>0,有f(n)=Ω(n^(log b(a)+ ε)),且對常數c<1與所有足夠大的n,有af(n/b)<=cf(n),則T(n)=Θ(f(n))
-
-
必會技能
- 遞歸式畫遞歸樹
-
課后習題總結
-
代換法證明時間復雜度
- 猜測漸進確界,證明之
- 主方法可用情況的練習
- 判斷主方法是否可用,確定漸進上界
-
第四章 堆與堆排序
-
堆的概念
- 利用樹的數組存儲方式,PARENT(i) = i/2, LEFT(i) = 2i, RIGHT(i) = 2i + 1
-
兩個關鍵的函數
- MAX-HEAPIFY 已有堆的情況下,加入新結點后調整堆以使得其滿足堆的條件。O(lgn)
- BUILD-MAX-HEAP 基於無序數組調整為大頂堆Θ(n)
- 其中,BUILD-MAX-HEAP是由(n/2)向下取整次MAX-HEAPIFY組成的,但其時間復雜度是Θ(n)
-
堆排序時間復雜度
- 時間復雜度由兩部分組成,1次BUILD-MAX-HEAP,n-1次MAX-HEAPIFY,故結果為T(n)=Θ(n)+nO(lg n)=O(nlgn)
- 最好的情況下,時間復雜度為O(n)
- 優先級隊列
-
必會技能:
- 區分一個數組是不是堆
- 手工跑堆排序或者建堆過程
-
課后習題總結:
- 區分一個序列是否為最大堆
- 畫出一個完整的MAX-HEAPIFY流程
第五章 快速排序
-
快速排序
-
時間復雜度
- 最好Θ(nlgn)
- 平均Θ(nlgn)
- 最壞Θ(n2)
- 知道分治的過程————以一個數做分治,分成兩組
- 掌握快排的手動做法
- 有一個關於每次都從1/10位置分隔的情況下仍為nlgn的證明
-
-
隨機快排
- 關鍵:用隨機來避免出現Worst case
- 實際表現是最快的排序
-
時間復雜度
- 平均Θ(nlgn)
- 最壞Θ(n2) (僅在理論上存在)
-
課后習題總結
- 若快排數組中元素都一樣,時間復雜度是多少?
- 答:這是Worst Case 所以是Θ(n2)
第六章 線性時間排序
- BDD證明基於比較排序最壞情況的最小量級是nlgn
-
計數排序
- 計數排序是一種穩定排序
- 時間復雜度Θ(k+n) ,在k與n同一數量級時,該復雜度為O(n)
-
關鍵:被排序的n個數在0~k之間
- 范圍不能超過數的個數的量級
- 若這n個數的范圍是n^2,則時間復雜度不再是O(n),而是O(n^2)
-
掌握計數排序的完整過程,可以手跑
- 創建一個容量為k的數組C,並將所有元素置零
- 遍歷原數組A,在C中對應的位置+1
- 遍歷數組C,從第2個元素開始的所有元素的值依次用前一個元素與當前元素的和替換。
- 逆序遍歷A,拿到元素a,在C中查找其位置(即C中元素對應的數值)在數組B中的對應位置放入a即可。同時將C中的那個數據-1
-
基數排序
- 掌握基數排序的完整過程,可以手跑
- 基數排序的特點:利用穩定排序的特點,從低位到高位按位排序
-
時間復雜度
- Θ(d T(n))
- 在每位計算使用計數排序的時候,時間復雜度為Θ(n)
-
桶排序
- 掌握桶排序的完整過程,可以手跑
- 主要針對均勻分布的數,利用哈西,靠散列的過程完成排序
- 要點:類似於計數排序,為待排序數組提供若干個區間,將各個待排序的數放進區間內,完成區間內排序的同時,就得到了一個完整的排序結果。
-
算法小結
- 區分原地排序
- 區分穩定排序
-
課后習題總結
- 推演一個計數排序的過程
第七章 中位數和順序統計
- 找到最大值/最小值的方法:找到最值Θ(n),從頭到尾遍歷,每一步記下當前的最值,結果就是最后的結果
-
查找第i個元素的隨機算法
- 存在Worst Case可以在線性時間完成計算的算法
-
了解PARTITION函數的作用及原理
- 該函數利用隨機數,拿到一個區間內的某數a,運行一次partition后,能保證以a為界將原區間分為兩個部分,選這兩個部分中的一部分繼續partition
- 優化后的partition主要在隨機拿到划分元素上下功夫,通過將所有元素5個一組分成小組,組內找出中位數,用所有的中位數再找出中位數a后,以a為界划分兩個部分,不斷循環,這樣能保證划分的質量。
第八章 動態規划(DP)
-
動態規划問題的四個基本步驟
- 確定最優解的結構。(DP的必要條件)
- 遞歸定義最優解的值。
- 自底向上計算解的值。
- 利用計算得到的信息構造最優解。
-
裝配線調度問題
- 關鍵:問題的最優解包含其子問題的最優解
-
遞推關系式
-
矩陣鏈乘
- 關鍵:拆分后的矩陣鏈也要以最少的計算次數才能得到正確的結果
-
遞推關系式
-
示意圖
-
DP問題的要素:最優子結構
- 有向圖中兩節點的最短路徑長度是有最優子結構的
- 有向圖中兩節點的最長路徑長度沒有最優子結構
- 最短路徑長度與最長路徑長度的區別是是子問題是否獨立。
-
自上而下與自底向上之間的比較
-
自上而下的遞歸形式算法
- 可能會存在重復計算的問題
- 有遞歸的時間開銷
-
自底向上的動態規划算法
- 沒有重復計算,但可能存在多余計算,即計算並不會用到的數據
-
-
備忘錄以及應用備忘錄后兩種形式算法的對比
- 備忘錄通過記錄計算過的子問題,避免了在自上而下進行遞歸計算時,重復計算的問題
-
自底向上的動態規划方法
- 需要計算所有情況
- 調用方式節省開銷
-
自上而下+備忘錄
- 只求解需要求解的子問題
- 遞歸調用產生多余的開銷
-
最長公共子序列(Longest common subsequence/LCS)
- 暴力算法:查找所有子串,時間復雜度是指數級
-
DP求解LCS原理
- 兩字符串A(m)、B(n),若最后一個字符相同則一定在其某個最長公共子序列C內,故C的長度為1+LCS(A(m-1),B(n-1))
- 兩字符串A(m)、B(n),若最后一個字符不相同,則C的長度為max{LCS(A(m-1),B(n)),LCS(A(m),B(n-1))}
- 由於上兩條,故LCS由AB某一子字符短的LCS組成,故具有最優子結構
-
DP求解LCS圖解
-
圖解的解釋:
- 用mn的空間記錄Ap,Bq時的LCS,從短到長記錄
-
從第一行開始一直到最后一行,查看每個格子所對應的橫縱字母
- 相同則取其左上方結果+1
- 不相同擇其上方或左方大者放入格子
-
最大子段和
-
DP求解最大子段和的原理
- 最大子段和一定是某個元素a加上了前面的某一個子段和或者是a元素本身。
-
DP求解數組A最大子段和過程
- B[0]=A[0]
- B[1…n]=max{B[1…n], B[0…n-1]+ B[1…n]}
- 遍歷B,其中的最值就是最大子段和
-
-
課后習題總結
- 修改原算法使其能順序輸出裝配結果
- 推演一個矩陣鏈乘的最優加括號方式
- 推演兩個字符序列的LCS
第九章 貪心算法4
-
貪心策略
- 貪心選擇性質:貪心策略希望通過局部選擇最優達到全局最優的目的。但是並不是所有情況都能達到全局最優。
-
活動選擇問題
-
活動選擇問題可以用動態規划求解,活動選擇問題存在最優子結構,如下:
-
活動選擇問題中的一個關鍵定理:對於任意子問題Sij,令am為Sij中結束時間最早的活動:
- 證明:若在最優解中,存在an為第一個活動,且an在am后結束,則an一定可以用am替換之。
- 由於定理帶來的特殊性質——貪心選擇性質,所以可以用貪心算法求解
- 貪心求解活動選擇問題:從頭開始不斷選出當前剩余活動中,滿足開始時間且結束時間最早的活動。
-
-
背包問題
包含0-1背包、分數背包兩個子問題
- 討論目的:從兩種背包問題中對比動態規划與貪心算法
-
異同點
- 共同點:均有最優子結構,符合動態規划問題的求解條件
-
不同點:針對同一物品確定是否選擇情況
- 分數背包:性價比最高的,一定在最優子結構中,因為其他的物品都達不到這種評價標准
- 0-1背包:不確定,需要對所有情況予以討論
-
解決策略:
-
分數背包:貪心算法
- 具體方法:把當前性價比最高的物品裝到不能再裝(沒有了或者包滿了)為止
-
0-1背包:DP
-
具體做法:刻畫最優子結構,標准DP做法
-
-
-
哈夫曼編碼
利用變長編碼使編碼長度大大減小,原理:頻率越高的字符,表示的編碼越短。
第十章 最短路徑算法
最短路徑算法包含單源最短路徑、每對結點間的最短路徑。。。。
-
關於最短路徑概念的討論
- 最短路徑滿足最優子結構,即:一個最短路徑a中的任意兩點的最短路徑b一定在a的路徑中
- 三角不等式:對於所有的 u,v,x∈V, 以下不等式成立 δ(u,v) ≤δ(u,x)+δ(x,v)
- 含有負環的圖中,某些最短路徑可能不存在5
- 單源最短路徑:求解從一個點到其他所有點的最短路徑的集合
-
狄傑斯特拉算法(單源)
狄傑斯特拉算法本質上利用了貪心思想,不斷的更新當前最短路徑,用來處理不含負邊的圖
- 時間復雜度:O(E+VlgV)
-
算法流程:
- 把原點a加入圖中。
- 記錄所有從原點能到達的結點的路徑長度,其他的記為∞
-
重復以下幾步,直到所有節點都記錄在圖中
- 選出未記錄到圖中的路徑v最小的那個結點p
- 把結點p加入圖中
- 用vp+p到其他結點的路徑長度與原記錄中的最短路徑對比,記下小的那個
-
無權圖的最短路徑算法(單源)
無權圖由狄傑斯特拉算法退化而來,通過廣度優先的的搜索模式記錄最短路徑
-
Bellman-Ford算法 (單源)
Bellman-Ford算法可以處理含有負邊、負環的圖,如果存在負環,則能報告由環為負環
-
每對結點間最短路徑
- V次Dijkstra:O(VE+V^2lgV)
-
V次Bellman-Ford:O(V^2E)
- 最壞情況(稠密圖):O(V^4)
-
每對結點間最短路徑第一種算法(矩陣“乘”)
-
每對結點間最短路徑第二種算法(Floyd)
- 概括:從1個點開始不斷往圖中增加點,如果新加入的點能夠對當前的最短路徑產生影響的話,就更新當前的最短路徑結果表;約束過哪些結點
-
遞歸式:
-
流程:
- 初始化一個矩陣存儲方式的V個邊的圖
-
循環下列步驟V次,記當前次數為k
- 對每一條路徑判斷,被k分為兩段的該路徑是否會得到更小的結果,用較小值更新它
-
每對結點間最短路徑第三種算法(Johnson)
- 概括:為了利用Dijkstra算法,於是通過更改權值,消除負權值以滿足Dijkstra。因為Dijkstra代價小
-
課后習題總結
- 推演一個Bellman-Ford算法
- 推演一個矩陣“乘”算法
- 推演一個Floyd算法
第十一章 回溯法&分支限界法
回溯法和分支限界法都是搜索搜索方式,當DP、貪心這些方法沒有辦法使用時,只能通過搜索來找到結果。搜索的方法主要包括這兩類。回溯法是一種深度優先的搜索方式
-
n皇后問題(回溯法)
- 解空間具有n!個n元組組成
-
算法步驟:
-
假設第一個在x的位置,x從0~n
-
假設第二個在y的位置,y從0~x-1,x+1~n
-
假設第二個在y的位置,z從0~n(不含x、y)
- ……
-
-
-
- 注意限界函數:不與其它皇后沖突
-
15迷問題(分支限界法)
- 15迷問題有一半的初始狀況無解
- 用回溯法的情況下,很大的幾率是浪費時間,沒有意義
-
采用LC-search(最小代價least cost)的15迷解法
- 對每一個分支進行打分,衡量其計算過的次數,以及其距離目標結果的差距個數。
- 選擇當前最好的那一個分支進行展開
- 循環以上操作,直到找到結果
-
子集合數(回溯法)
- 限界函數:既不超過目標數,剩下的數字和還大於距目標數的差距
-
01背包(回溯法)
- 限界函數:還有可能(通過分數背包計算剩下的產品價值)產生比當前的最優解好的情況才繼續搜索
-
回溯法的一般方法
- 遞歸調用
- for循環調用
第十二章 NP問題與一些概念
-
可計算性
- 不是所有問題都是可計算的
- 普斯特競賽問題(不可求解)
- 有限步操作確定一個給定的多元多項式是否有整數根問題(不可求解)
-
停機問題(不可求解)
- 證明(類似悖論)
-
NP完全
- P:在確定化的圖靈機上可在多項式級計算時間內求解的可判定問題集合。
- EXP:在確定化的圖靈機上可在指數級計算時間內求解的可判定問題集合。
- NP:存在有效驗證算法的可判定問題集合
-
NPC:NP集合中具有如下性質的問題:若該問題可被有效求解,則其求解方法可被用於有效求解其它NP完全問題。
- TSP:找到能否在距離D內訪問N個城市
- 三色問題:用三個顏色為地圖上色,要求鄰國顏色不一樣
- SAT:電路可滿足性
-
如何面對NPC問題?如果一個問題是NP完全問題,則我們所設計的算法最多能同時做到以下三點中的兩點:
- 求解問題的最優解
- 在多項式級時間內求解
- 求解問題的任一實例
- O,my god——助記,上帝、上界 ↩︎
- 歐米伽——助記,家在地上,下界 ↩︎
- θ的中間的一助記,那個橫足以說明是中間的啊~ ↩︎
- 個人理解,貪心算法能從動態規划演變成貪心,主要原因是,有一個准確的原因確定當前哪一個元素一定進入最優解 ↩︎
- 不是全部,因為,有些點之間不經過那個負環 ↩︎
- 原理,若有n個結點,則最短路徑最多在經過所有節點,也就是n-1個邊后得到最小值,否則說明有負環 ↩︎
- 這個過程稱為松弛,網上表示對此名稱有些疑問 ↩︎
- 一個圖的二階矩陣表示,其中對角線元素為0(表示自己到自己的距離為0),其余都是∞。幺元矩陣用來表示經過0個節點,圖中點到所有頂點的距離 ↩︎
- 只是借用說法,並不是一個乘法 ↩︎