1. Informal Goal: Connect a bunch of points together as cheaply as possible.
Blazingly Fast Greedy Algorithms:
- Prim's Algorithm
- Kruskal's algorithm
O(m log n) m is the # of edges and n is the # of vertices.
2. Problem Denition:
Input: Undirected graph G = ( V , E ) and a cost ce for each edge e in E.
- Assume adjacency list representation
- OK if edge costs are negative
Output: minimum cost ( sum of edge costs) tree T contained by E that spans all vertices .
Definition of spanning tree:
a) T has no cycles
b) The subgraph (V,T) is connected (i.e., contains path between each pair of vertices)
3. Standing Assumptions:
Assumption #1: Input graph G is connected.
- Else no spanning trees.
- Easy to check in preprocessing (e.g., depth-rst search).
Assumption #2: Edge costs are distinct.
- Prim + Kruskal remain correct with ties (which can be broken arbitrarily).
- Correctness proof a bit more annoying.
4. Prim's MST Algorithm:
- Initialize X = {s} [s in V chosen arbitrarily]
- T = empty set [invariant: X = vertices spanned by tree-so-far T]
- While X <> V
- Let e = (u, v) be the cheapest edge of G with u in X, v not in X.
- Add e to T
- Add v to X.
While loop: Increase # of spanned vertices in cheapest way possible.
5. Denition of Cut : A cut of a graph G = (V , E) is a partition of V into 2 non-empty sets. ( at most 2^(n-1) -1 cuts)
6. Empty Cut Lemma: A graph is not connected <==> exists a cut (A , B) with no crossing edges.
Proof : <== choose u in A and v in B , there is no path from u to v.
==> for (u, v) in G, that there is no path from u to v, Define :
A = {Vertices reachable from u in G}
B = V - A
So, no edge from A to B, otherwise A will be bigger
7. Double-Crossing Lemma: Suppose the cycle C in E has an edge crossing the cut (A , B): then so does some other edge of C. ( the crossing edge of C should be even)
8. Lonely Cut Corollary: If e is the only edge crossing some cut (A , B), then it is not in any cycle.
9. Claim: Prim's algorithm outputs a spanning tree.
Proof: (1) Algorithm maintains invariant that T spans X
(2) Can't get stuck with X <> V (other wise cut {X, V-X} has no crossing edge ==> G is disconnected
(3) No cycles ever get created in T. A newly added edge e is the 1st edge crossing (X , V - X) that gets added to T ==> its addition can't create a cycle in T
10. Cut Property: Consider an edge e of G. Suppose there is a cut (A , B) such that e is the cheapest
edge of G that crosses it. Then e belongs to the MST of G.
Proof : Suppose there is an edge e that is the cheapest one crossing a cut (A , B), yet e is not in the MST T*.
Idea: Exchange e with another edge in T* to make it even cheaper(contradiction).
Since T* is connected, must construct an edge f (<> e) crossing (A , B).
However exchange f with e may make T* not a spanning tree :
How to find e' : Let C = cycle created by adding e to T*. ( there is already path between the nodes connected by e, so adding e to T* constructs a cycle)
By the Double-Crossing Lemma: Some other edge e' of C [with e' <> e and e' in T] crosses (A , B).
T = T * U {e} - {e'} is also a spanning tree. Since ce < ce' , T cheaper than purported MST T*
11. Claim: Cut Property ==> Prim's algorithm is correct.
Proof: By previous video, Prim's algorithm outputs a spanning tree T*.
Key point: Every edge e in T* is explicitly justied by the Cut Property.
==> T* is a subset of the MST
==> Since T* is already a spanning tree, it must be the MST
12. Running time of straightforward implementation:
- O(n) iterations [where n = # of vertices]
- O(m) time per iteration [where m = # of edges]
==> O(mn) time
13. Prim's Algorithm with Heaps:
Invariant #1: Elements in heap = vertices of V - X.
Invariant #2: For v in V - X, key[v] = cheapest edge (u , v) with u in X (or infinitive if no such edges exist).
Given invariants, Extract-Min yields next vertex v not in X and edge (u , v) crossing (X , V - X) to add to X and T, respectively.
Can initialize heap with O( m + n log n ) = O(m log n) preprocessing. Inserts m >= n - 1 since G connected.
Pseudocode: When v added to X:
- For each edge (v , w) in E:
- If w in V - X ==> The only whose key might have changed (Update key if needed:)
- Delete w from heap
- Recompute key[w]:=min{key[w],cvw}
- Re-Insert into heap
14. Running Time with Heaps :
- Dominated by time required for heap operations
- (n - 1) Inserts during preprocessing
- (n - 1) Extract-Mins (one per iteration of while loop)
- Each edge (v , w) triggers one Delete/Insert combo
[When its 1rst endpoint is sucked into X]
==> O(m) heap operations [ m >= n - 1 since G connected]
==> O(m log n) time [As fast as sorting!]
相关推荐
常见的MST算法有Kruskal's Algorithm和Prim's Algorithm: 1. **Kruskal's Algorithm**:这个算法基于贪心策略,按边的权重从小到大依次考虑。每次选择一条不形成环的新边加入到当前的生成树中。这个过程持续到所有...
最大生成树的构建通常基于贪心策略,其中最著名的算法之一是Kruskal's Algorithm和Prim's Algorithm。在本例中,描述提到的是一个针对最大生成树的算法实现,但并未明确指出具体使用了哪种算法。Kruskal's Algorithm...
在`PrimMST`文件中,可以找到Prim算法的C++实现,包括邻接矩阵或邻接表的表示、优先队列的使用以及算法的主体部分。 **代码解析** `KruskalMST`和`PrimMST`文件分别实现了Kruskal和Prim算法。代码可能包含以下几个...
Prim’s MST algorithm是另一个使用Greedy Technique的经典算法,用于解决minimum spanning tree问题。该算法的步骤是: 1. 选择一个顶点作为起始顶点,构建初始树T1。 2. 在每次迭代中,从当前树Ti中选择最近的...
最小生成树(Minimum Spanning Tree, MST)是图论中的一个重要概念,主要应用于网络设计、数据传输优化等领域。Prim算法是解决此问题的一种经典方法,由捷克数学家Vojtěch Jarník在1930年提出,后经美国计算机科学...
在本压缩包文件"**MST.rar**"中,包含了两种经典的MST算法的实现:克鲁斯卡尔(Kruskal's Algorithm)和普里姆(Prim's Algorithm)。 首先,我们来看克鲁斯卡尔算法。这是一种基于边的贪心策略,它按照边的权重...
在本教学课件“21_Graph_04.pdf”中,主要讨论了图(Graph)的一个重要应用——最小生成树(Minimum Spanning Tree,MST),以及求解最小生成树的两种经典算法:Kruskal's Algorithm 和 Prim's Algorithm。...
如果你对这个主题感兴趣,可以进一步探索图论的其他概念,如最短路径算法(Dijkstra's algorithm或Floyd-Warshall algorithm)、最大流最小割问题等,这些都是图论在计算机科学中的基础且实用的部分。
5. Kruskal's算法和Prim's算法:用于计算图的最小生成树,前者基于边的贪心策略,后者基于节点的贪心策略。`nx.kruskal_mst(G)` 和 `nx.prim_mst(G)` 分别对应这两个算法。 6. 强连通分量:找出图中所有相互可达的...
Prim算法是一种用于寻找图中所有顶点构成的最小生成树(Minimum Spanning Tree, MST)的经典算法之一。它适用于带权无向图,并且能够确保得到的MST具有最小的总权重。Prim算法的核心思想是从任意一个顶点出发,逐步...
- Prim's Algorithm:普里姆算法,从一个顶点开始,逐步扩展到相邻的顶点,每次选择连接两个已分隔部分的最小权重边。可以使用优先队列(如二叉堆)实现,以高效地找到最小权重边。 2. **性质与定理** - Cut ...
本话题主要关注如何在图中找到一个成本最低的子集,即最小生成树(Minimum Spanning Tree, MST),它可以连接所有顶点而使得边的总权重最小。我们将探讨两种经典的算法:Prim算法和Kruskal算法,它们都是用C++实现的...
Kruskal's Algorithm和Prim's Algorithm是两种常用的解决MST问题的算法。 Fibonacci树是一种特殊的树结构,由Fibonacci序列定义,通常用于数据结构和算法的教学与研究。将Fibonacci树与最小生成树相结合,可能是...
(1) Given a undirected Graph G=(V, E) like below, to calculate the minimum spanning tree using Kruskal’s algorithm and Prim’s algorithm. 4. Experimental Requirement 1)The template should be ...
普鲁姆算法(Prim's Algorithm),也称为普鲁母最小生成树算法,是由Vaclav J. Prim在1930年提出的,是一种贪心算法,用于解决寻找最小生成树的问题。该算法从图中的任意一个顶点开始,逐步增加边,每次添加的边都是...
Prim's minimum spanning tree Kruskal MST Directed/Undirected graph ops Breadth First Search Depth First Search Dijkstra's algorithm Bellman-Ford algorithm Edmonds-Karp Maximal Flow Push–Relabel ...
#include <algorithm> #include using namespace std; const int INFINITE = 1 ; struct Edge { int v; // 边端点 int w; // 边权值 Edge(int v_ = 0, int w_ = INFINITE) : v(v_), w(w_) {} bool operator<...
+ Prim 求 MST(最小生成树) + 次小生成树 O(V^2) + 最小生成森林问题(k 颗树)O(mlogm) + 有向图最小树形图 + Minimal Steiner Tree + Tips K 度最小生成树 * 最短路径 + 最短路径模版(Dijkstra) 邻接表+...
常见的并行MST算法有Kruskal's算法和Prim's算法的并行版本。下面我们将深入探讨这两种算法及其并行化策略。 1. **Kruskal's Algorithm 并行化** Kruskal's算法是基于贪心策略的,它按边的权重从小到大选择边,并...
常见的算法有克鲁斯卡尔(Kruskal's Algorithm)和普里姆(Prim's Algorithm)。 克鲁斯卡尔算法是一种贪心策略,它按照边的权重从小到大依次考虑,每次选择一条不构成环的边加入到当前的生成树中,直到所有的顶点...