一、贪心算法
- 一步一步扩大solution
- 每一步从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求解
- Prim’s algorithm
- Difficult selecting: “best local optimization means * no cycle and small weight under limitation. *
- Easy checking: doing nothing
Kruskal’s algorithm
- Easy selecting: smallest in primitive meaning
- Difficult checking: no cycle
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.在一个连通有权图G=(V,E,W)中,一棵生成树T是最小生成树当且仅当T拥有MST property。
- 证明Prim’s 算法的正确性
- 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(n∗T(getMin)+n∗T(deleteMin+insert)+m∗T(decreaseKey))
Implementing priority queue using array, we can get
θ(n2+m)
另外附加一个连接:优先级队列详解