【算法概論】5.貪心算法

5 貪心算法

  • 貪心算法採取步步逼近的方式構造問題的解,其下一步的選擇總是在當前看來收效最快和效果最明顯的那一個。

5.1 最小生成樹

  • 性質1:移除環中的任意一條邊不會破壞圖的連通。
  • 性質2:具有n各節點的樹的邊數爲n-1。
  • 性質3:任何一個連通無向圖G=(V,E),若滿足|E|=|V|-1,則其爲樹。
  • 性質4:一個無向圖是樹,當且僅當在其任意兩個節點間僅存在唯一路徑。
  • 最小生成樹無向圖的一個連通無環子圖,且總權重最小5.1 minimum spanning tree

5.1.1 一個貪心方法

  • Kruskal最小生成樹算法:
    • 起始於一個空圖
    • 不斷從E中選擇邊:
    • 不斷重複地選擇未被選中的邊中權重最輕且不會形成環的一條

5.1.2 分割性質

  • 分割性質
    XG=(V,E)SV使XSVSeSVSX{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 一種用於分離集的數據結構

  • 基於等級的合併:

使用有向樹存儲集合:節點包含父指針,根節點爲集合代表,其父指針指向自身。每個節點還有一個等級信息,代表節點的高度。

5.5 A directed-tree representation of two sets

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

其中,合併後樹的高度爲log|V| ,則find(u)的時間複雜度爲O(log|V|)

  • 路徑壓縮:
function find(x)
    if x≠π(x):
        π(x)=find(π(x))
    return π(x)

5.7 The effect of path compression-find ( I ) followed by find ( K )

經過路徑壓縮後,find(u)的時間複雜度降爲略高於O(1)

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後代)

樹的葉節點代表一個字符。

(cost)=i=1nfi(i)=+()
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),右側爲肯定文字——(zw)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 集合覆蓋

  • 集合覆蓋問題:

輸入:BS1,S2,...,SmB

輸出:Si使B

成本:所選出集合數量

貪心算法:選取包含未被覆蓋元素的最大集合Si ,不斷重複,直到B中所有元素被覆蓋。(無法得到最優解)

斷言:設B有n個元素,且其最優覆蓋共包含k個集合,則貪心算法所得結果最多包含kln n 個集合。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章