算法14讲——MST/Greedy

来源:互联网 发布:java初学者知乎 编辑:程序博客网 时间:2024/06/06 16:26

一、贪心算法

  1. 一步一步扩大solution
  2. 每一步从candidates中选择时,必须满足:
    • 可行性:必须满足问题要求
    • 局部最优:必须是这一步所有candidates中最好的选择
    • 不可撤销:这一步不可被后面的选择撤销
set greedy(set candidate) set S=Ø; while not solution(S) and candidate≠Ø select locally optimizing x from candidate; candidate=candidate‐{x}; if feasible(x) then S=S∪{x}; if solution(S) then return S else return (“no solution”) 

二、MST求解

  1. Prim’s algorithm
    • Difficult selecting: “best local optimization means * no cycle and small weight under limitation. *
    • Easy checking: doing nothing
  2. Kruskal’s algorithm

    • Easy selecting: smallest in primitive meaning
    • Difficult checking: no cycle
  3. Minimum Spanning Tree Property(MST性质)
    在一个连通有权图中的生成树T有MST property 当且仅当对于任意一个非tree-edge边uv,T
    ∪{uv}包含一个环并且uv是其中权值最大的边。
    All the spanning trees having MST property have the same weight.

  4. 在一个连通有权图G=(V,E,W)中,一棵生成树T是最小生成树当且仅当T拥有MST property。

  5. 证明Prim’s 算法的正确性
  6. Prim’s算法
    Main Procedure
primMST(G,n)     Initialize the priority queue pq as empty;     Select vertex s to start the tree;     Set its candidate edge to (‐1,s,0);     insert(pq,s,0);     while (pq is not empty)         v=getMin(pq); deleteMin(pq);         add the candidate edge of v to the tree;         updateFringe(pq,G,v);     return 

* ADT operation executions: *
- insert, getMin, deleteMin: n times
- decreaseKey: m times

desreaseKey(p,m)操作降低在位置p处的值,降值幅度为正m,不过这种方式很可能破坏堆序性,因此需要通过上滤操作进行调整。这种方式能够动态的提高某个任务的优先级,使其在能够优先开始。

getMin(pq)为边集中拥有最小关键码的顶点

Updating the Queue

updateFringe(pq,G,v)     For all vertices w adjcent to v //2m loops         newWgt=w(v,w);         if w.status is unseen then             Set its candidate edge to (v,w,newWgt);             insert(pq,w,newWgt)         else             if newWgt<getPriorty(pq,w)                 Revise its candidate edge to (v,w,newWgt);                 decreaseKey(pq,w,newWgt)     Return 

复杂度分析:应用ADT优先级队列(图G n个顶点,m条边

  • insert: n;
  • getMin: n ;
  • deleteMin: n ;
  • decreaseKey: m (appears in 2m loops, but execute at most m)

T(n,m)=O(nT(getMin)+nT(deleteMin+insert)+mT(decreaseKey))
Implementing priority queue using array, we can get θ(n2+m)

另外附加一个连接:优先级队列详解