5 貪心算法
- 貪心算法採取步步逼近的方式構造問題的解,其下一步的選擇總是在當前看來收效最快和效果最明顯的那一個。
5.1 最小生成樹
- 性質1:移除環中的任意一條邊不會破壞圖的連通。
- 性質2:具有n各節點的樹的邊數爲n-1。
- 性質3:任何一個連通無向圖G=(V,E),若滿足|E|=|V|-1,則其爲樹。
- 性質4:一個無向圖是樹,當且僅當在其任意兩個節點間僅存在唯一路徑。
- 最小生成樹:無向圖的一個連通無環子圖,且總權重最小。
5.1.1 一個貪心方法
- Kruskal最小生成樹算法:
- 起始於一個空圖
- 不斷從E中選擇邊:
- 不斷重複地選擇未被選中的邊中權重最輕且不會形成環的一條
5.1.2 分割性質
- 分割性質:
設邊集X是G=(V,E)的某個最小生成樹的一部分。選定任一節點集合S⊂V,使得X中沒有跨越S和V−S的邊。若e是跨越S和V−S的權重最輕的邊,則X∪{e}也是某個MST的一部分。
5.1.3 Kruskal算法
procedure kruskal(G,w)
Input: A connected undirected graph G=(V,E) with edge weights w_e
Output: A minimum spanning tree defined by edges X
for all u ∈ V:
makeset(u) //創建一個僅包含u的獨立集合
X={}
sort the edges E by weight
for all edges (u,v) ∈ E,in increasing order of weight:
if find(u)≠find(v): //find(u):找出u屬於的集合
add edge (u,v) to X
union(u,v)
5.1.4 一種用於分離集的數據結構
- 基於等級的合併:
使用有向樹存儲集合:節點包含父指針,根節點爲集合代表,其父指針指向自身。每個節點還有一個等級信息,代表節點的高度。
procedure makeset(x)
π(x)=x
rank(x)=0
function find(x)
while x≠π(x):
x=π(x)
return x
procedure union(x,y) //讓較低的樹根指向較高的樹根
r_x = find(x)
r_y = find(y)
if r_x==r_y:
return
if rank(r_x)>rank(r_y):
π(r_y)=r_x
else:
π(r_x)=r_y
if rank(r_x)==rank(r_y):
rank(r_y)=rank(r_y)+1
其中,合併後樹的高度爲
- 路徑壓縮:
function find(x)
if x≠π(x):
π(x)=find(π(x))
return π(x)
經過路徑壓縮後,find(u)的時間複雜度降爲略高於
5.1.5 Prim算法
function prim(G,w)
Input: A connected undirected graph G=(V,E) with edge weights w_e
Output: A minimum spanning tree defined by the array prev
for all u ∈ V:
cost(u)= ∞
prev(u)=nil
pick any initial node u0
cost(u0)=0
H=makequeue(V) //priority queue,using cost-values as keys
while H is not empty:
v=deletemin(H)
for each (v,z) ∈ E:
if cost(z)>w(v,z)
cost(z)=w(v,z)
prev(z)=v
與Dijkstra算法區別僅在於——優先隊列排序的鍵值:
- Dijkstra算法使用
dist(z)=min(dist(z),dist(v)+l(v,z))
——起始點到某節點的路徑長度 - Prim算法使用
cost(z)=min(cost(z),w(v,z))
——集合S中點到某節點的邊權重
5.2 Huffman編碼
任一無前綴編碼都可以表示爲一個完全爲二叉樹。(要麼0後代,要麼2後代)
樹的葉節點代表一個字符。
function huffman(f)
Input: An array f[1...n] of frequencies
Output: An encoding tree with n leaves
let H be a priority queue of integers, ordered by f
for i=1 to n:
insert(H,i)
for k=n+1 to 2n-1:
i=deletemin(H)
j=deletemin(H)
create a node numbered k with children i,j
f[k]=f[i]+f[j]
insert(H,k)
5.3 Horn公式
Horn公式:表達邏輯事實、進行推理
- 蘊涵式:左側爲肯定文字的並(AND),右側爲肯定文字——
(z∧w)⇒u - 純否定子句:任意多個否定文字的或(OR)——
(¬u∨¬v∨¬y)
function horn(implication,pure negative clause)
Input: A Horn formula
Output: A satisfying assignment, if one exits
set all variables to false
while there is an implication that is not satisfied:
set the right-hand variable of the implication to true
if all pure negative clauses are satisfied:
return assignment
else:
return "formula is not satisfiable"
5.4 集合覆蓋
- 集合覆蓋問題:
輸入:
輸出:
成本:所選出集合數量
貪心算法:選取包含未被覆蓋元素的最大集合
斷言:設B有n個元素,且其最優覆蓋共包含k個集合,則貪心算法所得結果最多包含