算法設計複習筆記
引言
穩定匹配問題
現在有N位男生和N位女生,每個男生都對N個女生的喜歡程度做了排序,每個女生都對N個男生的喜歡程度做了排序,現在需要確定一個穩定的約會狀態。
穩定的定義:如果男生i和女生a牽手,但男生i對女生b更喜歡,而女生b發現,相比自己的男朋友j,她更喜歡男生i,則沒有力量阻礙男生i和女生b的私奔,這即是不穩定的。
設計一個算法解決穩定匹配問題,具體步驟參見鏈接。
算法
設計算法需要考慮到算法的正確性,有窮性和輸出。也即正確性,有窮性,可行性,0或多個輸入,一或多個輸出。
算法設計步驟
- 如何從一個實際的問題中抽取出具有本質性的問題描述。
- 能夠設計有效的算法解決問題。
- 分析算法的步驟及最後的結果。
- 能夠以小見大,用理論來解釋一些現象。
區間調度問題
可用貪心算法求解。
帶權的區間調度問題
可用動態規劃求解。具體步驟參見鏈接。
二分匹配問題
選擇性的回溯,歸納的建立越來越大的匹配;這種處理叫做增廣。網絡流問題中,增廣構成了其中的核心要素。
最大獨立集問題
獨立集問題稱爲NP完全這一大類問題中的一個。
NP完全問題:Non-deterministic Polynomial(多項式複雜程度的非確定性問題)。
驗證和求解在難度上有很大的差別。
競爭的便利店選址問題
PSPACE完全問題類。
PSPACE完全問題嚴格難於NP完全問題。
PSPACE完全的概念涉及到對策策略,規劃,人工智能領域的基本課題。
算法分析基礎
什麼叫一個算法好?運行有效率?
定義效率1:當實現一個算法時,如果它在真實的實例上運行的快,那麼這個算法是有效的。
缺點:平臺,實例,輸入規模。
定義效率2:在分析的層次上,如果一個算法與蠻力搜索比較,最壞情況下達到質量上更好的性能,就說這個算法是有效的。
問題:什麼是質量上更好?
定義效率3:如果一個算法有多項式運行時間,稱爲這個算法是有效的。
- 來自於數學形式和經驗證據。
- 不絕對反映真實的運行時間。
- 符合實際情況的合理近似。
多項式時間:一個算法被稱爲是多項式時間的,當且僅當滿足以下條件:
- 當算法輸入的規模增長時,算法運行時間是多項式有界的。
- 即存在常數 , ,使得對於每一個規模爲N的輸入實例,算法的運行時間不超過 。
定義效率的意義
有利於一般性的研究:
- 清楚的表達:對某個問題不存在有效的算法。
- 算法的研究轉入高質量科學的先決條件。
- 問題具有固有的計算可解性的層次:
- 某些能夠被有效地求解。
- 某些不能夠被有效地求解。
爲什麼需要增長的漸進階這樣一個概念?
- 得到一個準確的界是很困難的。
- 目標是識別類似行爲算法的大類,按照粗粒度進行分析。
- 算法執行的步數可能依賴於所使用的語言。
定義O,Ω和Θ,希望以不受常數因子和低項影響的方式表達運行時間的增長率
漸進的上界O:
- 如果存在常數 和 ,使得對所有 ,有 ,那麼 是 的。
- 是 的漸進上界。
- 要求存在一個對所有n有效的常數c。
漸進的下界Ω:
- 如果存在常數 和 ,使得對所有 ,有 ,那麼 是 的。
- 是 的漸進下界。
- 要求存在一個對所有n有效的常數ε。
漸進的緊Θ:
- 如果 既是 且也是 的,我們就說 是 的。
- 是關於 的一個漸進的緊的界。
示例
亞線性時間
給定一個排好序的含有n個數的數組A,我們想確定一個給定的數p是否屬於這個數組。
採用二分查找算法。
時間複雜度:
線性時間
計算n個數 中的最大數。
歸併兩個排好序的數表。
時間複雜度:
階時間
快速排序。
快速傅里葉變換。
歸併排序。
堆排序。
平方時間
平面上給定n個點,由(x,y)表示座標。找最鄰近的點對。
時間複雜度:
立方時間
給定集合 ,均爲 的子集,求這些子集中是否有某對子集是不相交的。
時間複雜度:
階時間
給定的n個結點的輸入圖,確定是否有一個大小爲k的獨立集。
時間複雜度:
指數時間
給定一個圖,需要找一個最大規模的獨立集。
時間複雜度:
n!時間
穩定匹配問題的窮舉搜索。
巡迴售貨員問題。
時間複雜度:
圖
圖的表示:鄰接矩陣,鄰接鏈表。
路徑:無向圖G=(V,E)中,如下結點序列 ,其中 是E中的一條邊,則此結點序列被稱爲從 到 的路徑。
簡單路徑:如果一條路徑所有的結點都是相互不相同的,就稱爲簡單的。
連通:如果對於無向圖中任意兩個頂點u,v都存在一條路徑,那麼無向圖被稱爲是連通的。
圈:路徑 被稱爲一個圈,如果 ,而且前k-1個頂點兩兩不同。
樹:一個無向圖被稱爲是樹,如果它是連通的而且沒有圈。
鄰接矩陣
佔用 的空間;檢查給定的邊是否出現在圖中,時間複雜度爲 。
鄰接鏈表
佔用 的空間,m爲邊的數目;檢查給定的邊是否出現在圖中,時間複雜度爲 。
寬度優先搜索
用隊列來維護即將被處理的節點。
深度優先搜索
用棧來維護即將被處理的節點。
二分性測試
如果一個圖時二部圖,那麼它不可能包含一個奇圈。
寬度優先搜索,G中沒有邊與同一層的兩個結點相交。
拓撲排序
有向無圈圖DAG。
如果G有一個拓撲排序,那麼G是一個DAG。
在每一個DAG中,存在一個沒有輸入邊的結點。
每次取那個沒有輸入邊的結點,加入拓撲排序。
貪心算法
一個算法時貪心的,如果:
- 此算法時通過一些小的步驟來建立一個解。
- 在每一步根據局部情況選擇一個決定。
- 使得某些主要的指標能得到優化。
一個問題可以被貪心算法求解
- 問題本身結果有關的一些性質。
- 存在一個局部判斷規則。
- 可以用來構造問題的最優解。
兩種基本方法證明一個問題能夠用貪心算法求得最優解
- 貪心算法領先
- 每一步都比其他的算法好。
- 證明產生了一個最優解。
- 交換論證
- 考慮對這個問題的任何可能解。
- 把它轉換成由貪心算法找到的解。
- 不影響解的質量。
- 證明貪心算法找到了一個至少與其他解一樣好的解。
區間調度問題
每一次選擇儘早結束的需求。
- 按結束順序排序。
- 每次選擇第一個區間,按次序迭代。
時間複雜度:
區間劃分
沒看懂。
最小延遲調度
保證具有最早截止時間的任務最早完成。
- 按照結束時間增長的次序排序。
- 最早截止時間優先。
最優超高速緩存
簡化調度:在第i步有對d的需求;d不在超高速緩存中,考慮在第i步只放入項d的調度。
一個圖的最短路徑
Dijkstra算法。
最小生成樹問題
Kruskal算法。
反向刪除算法。
Prim算法。
聚類
最大間隔聚類
- 定義距離
- 按照距離增加的次序增加邊
- 如果已經屬於同一個聚類則不添加,每一添加一條橫跨兩個不同連通分支的邊。
單鏈聚類
- 定義距離。
- 最小生成樹算法。
- 刪除k-1條最貴的邊。
哈夫曼編碼
採用優先隊列(堆實現):每次插入,取出最小元素( ),總運行時間( )。
動態規劃
貪心算法
- 利用局部最優化原理,逐漸建立起完整的最優解。
- 構成算法設計最自然的方法。
- 對人們碰到的大多數問題,實際困難不在於確定幾個貪心策略中哪一個是正確的,而是事實上可能不存在有效的貪心算法。
動態規劃
- 把事情分解爲一系列子問題。
- 對越來越大的子問題建立正確的解。
- 隱含的探查所有可行解的空間:
- 穿過問題可行解的指數規模集合。
- 不必明確檢查所有的解。
帶權的區間調度
動態規劃原理
思路一
- 設計一個(指數時間的)遞歸算法。
- 通過備忘錄轉換成一個有效的遞推算法。
- 利用全局數組來記錄遞歸函數值。
思路二
- 在子問題上迭代,而不是遞歸地計算解。
動態規劃類型問題
- 只存在多項式個子問題。
- 容易從子問題的解計算初始問題的解。
- 子問題從“最小”到“最大”存在自然的順序關係。
- 與一個容易計算的遞推式相聯繫。
- 允許更小的子問題來確定一個子問題的解。
動態規劃過程
- 刻畫最優解的結構。
- 構造最優值的遞歸關係表達式。
- 按照自底向上或自頂向下的方式計算最優值。
- 構造最優解。
分段的最小二乘
我賭不考,沒看。
揹包問題
if wi > w
OPT(i,w) = OPT(i-1,w)
else
OPT(i,w) = max{
OPT(i-1,w),
vi+OPT(i-1,w-wi)
}
設計一個自底向上的算法,逐步填滿一個n·W的二維數組。也可以爲(n+1)·(W+1)。
時間複雜度:
RNA二級結構
滿足:
- 沒有尖的轉彎:每個對的兩段被至少四個插入的鹼基所分隔。
- A-U,U-A,C-G,G-C。
- 不交叉。
if j - i < 4
OPT(i,j) = 0
else
OPT(i,j) = max{
OPT(i,j-1),
1 + maxt{OPT(i,t-1) + OPT(t+1,j-1)}
}
//maxt遍歷所有的t,使得bt與bj是一對被允許的鹼基
序列比對
定義距離:
- 空隙罰分δ。
- 不匹配罰分 。
if i = 0
OPT(i,j) = jδ
else if j = 0
OPT(i,j) = iδ
else
OPT(i,j) = min{
α_xiyj + OPT(i-1,j-1),
δ + OPT(i-1,j),
δ + OPT(i,j-1)
}