Download presentation
Presentation is loading. Please wait.
1
Eager Prim Dijkstra
2
Minimum spanning tree Minimum spanning tree (MST) Prim v.s. Kruskal
is a spanning tree whose weight is not larger than any other spanning tree Prim v.s. Kruskal Prim: At each time, add an edge connecting tree vertex and non-tree vertex Minimum-weight crossing edge MinPQ, IndexMinPQ Kruskal gradually add minimum-weight edge to the MST, avoid forming cycle Union-find, MinPQ
3
Prim Look for the minimum-weight crossing edge Tree edge (thick black)
Ineligible edge (dotted line) Crossing edge (solid line) Minimum-weight crossing edge (thick red) Minimum-weight crossing edge
4
Prim Look for the minimum-weight crossing edge Vertices on the MST
masked[v]==true/false Edges on the tree edgeTo[v] is the Edge that connects v to the tree Crossing edges MinPQ<Edge> that compares edges by weight Minimum-weight crossing edge
5
Lazy Prim private void prim(EdgeWeightedGraph G, int s) { scan(G, s);
while (!pq.isEmpty()) Edge e = pq.delMin(); int v = e.either(), w = e.other(v); if (marked[v] && marked[w]) continue mst.enqueue(e); weight += e.weight(); if (!marked[v]) scan(G, v); if (!marked[w]) scan(G, w); } W After putting V into to MST, both of the edges associated with W are in the priority queue private void scan(EdgeWeightedGraph G, int v) { marked[v] = true; for (Edge e : G.adj(v)) if (!marked[e.other(v)]) pq.insert(e); }
6
Lazy Prim Example Min PQ (A, D): 1 (A, B): 2 (A, G): 3 (A, E): 4
(A, C): 5 B B 4 2 D D 2 C C 1 5 A A 2 3 4 G G E F E F 3
7
Lazy Prim Example Min PQ (A, D): 1 (A, B): 2 (D, E): 2 (A, G): 3
(A, E): 4 (B, D): 4 (A, C): 5 B B 4 2 D D 2 C C 1 5 A A 2 3 4 G G E F E F 3
8
Lazy Prim Example Min PQ (A, D): 1 (A, B): 2 (D, E): 2 (B, C): 2
(A, G): 3 (A, E): 4 (B, D): 4 (A, C): 5 B B 4 2 D D 2 C C 1 5 A A 2 3 4 G G E F E F 3
9
Lazy Prim Example Min PQ (A, D): 1 (A, B): 2 (D, E): 2 (B, C): 2
(A, G): 3 (E, F): 3 (A, E): 4 (B, D): 4 (A, C): 5 B B 4 2 D D 2 C C 1 5 A A 2 3 4 G G E F E F 3
10
Lazy Prim Example Min PQ (A, D): 1 (A, B): 2 (D, E): 2 (B, C): 2
(A, G): 3 (E, F): 3 (A, E): 4 (B, D): 4 (A, C): 5 B B 4 2 D D 2 C C 1 5 A A 2 3 4 G G E F E F 3
11
Lazy Prim Example Min PQ (A, D): 1 (A, B): 2 (D, E): 2 (B, C): 2
(A, G): 3 (E, F): 3 (A, E): 4 (B, D): 4 (A, C): 5 B B 4 2 D D 2 C C 1 5 A A 2 3 4 G G E F E F 3
12
Lazy Prim Example Min PQ (A, D): 1 (A, B): 2 (D, E): 2 (B, C): 2
(A, G): 3 (E, F): 3 (A, E): 4 (B, D): 4 (A, C): 5 B B 4 2 D D 2 C C 1 5 A A 2 3 4 G G E F E F 3
13
Think about Eager Prim Lazy Prim Eager Prim elge
Textbook implementation (quiz answer) vlge (simple optimization) For a graph which has v node, there are v-1 edges in the spanning tree while (!pq.isEmpty()) // break the loop if there is already v-1 edges in the MST Eager Prim vlgv v edges in the MinPQ instead of e edges How?
14
Think about Eager Prim Min PQ (A, D): 1 (A, B): 2 (D, E): 2 (A, G): 3
(A, E): 4 (B, D): 4 (A, C): 5 B B 4 2 D D 2 C C 1 5 A A 2 3 4 G G E F E F 3 Is that necessary to keep both (A, B) and (B, D) in the MinPQ? Is that necessary to keep both (A, E) and (D, E) in the MinPQ?
15
Lazy Prim v.s. Eager Prim Is that necessary?
We already have <A,W> in the PQ, now we want to add <V,W> to the PQ. One of the edge is redundant since they connected to the same vertex W. We only need the smaller of the two since we are looking for minimum-weight crossing edge. How about this, we store <?,W> in the PQ, <?,W> denotes the minimum weight from MST to non-MST vertex W. (EdgeTo[w] and distTo[w]) After putting V into to MST, both of the edges associated with W are in the priority queue V W A
16
Lazy Prim v.s. Eager Prim Is that necessary?
When we want to put <V,W> into the PQ, we search for index key W to see if <?,W> exists. Therefore, we need to use a IndexPriority Queue. In which the vertex numbers (e.g. W) are the index key and the weights are the sorting key. After putting V into to MST, both of the edges associated with W are in the priority queue V W A
17
Lazy Prim v.s. Eager Prim private void scan(EdgeWeightedGraph G, int v) { marked[v] = true; for (Edge e : G.adj(v)) { int w = e.other(v); if (marked[w]) continue if (e.weight() < distTo[w]) { distTo[w] = e.weight(); edgeTo[w] = e; if (pq.contains(w)) pq.changeKey(w, distTo[w]); else pq.insert(w, distTo[w]); } V W A Eager Prim keeps only the smaller of <A,W> and <V,W> in the IndexPriorityQueue
18
Eager Prim private void prim(EdgeWeightedGraph G, int s) {
distTo[s] = 0.0; pq.insert(s, distTo[s]); while (!pq.isEmpty()) { int v = pq.delMin(); scan(G, v); } Eager Prim public PrimMST(EdgeWeightedGraph G) { edgeTo = new Edge[G.V()]; distTo = new double[G.V()]; marked = new boolean[G.V()]; pq = new IndexMinPQ<Double>(G.V()); for (int v = 0; v < G.V(); v++) distTo[v] = Double.POSITIVE_INFINITY; if (!marked[v]) prim(G, v); assert check(G); } private void scan(EdgeWeightedGraph G, int v) { marked[v] = true; for (Edge e : G.adj(v)) { int w = e.other(v); if (marked[w]) continue if (e.weight() < distTo[w]) { distTo[w] = e.weight(); edgeTo[w] = e; if (pq.contains(w)) pq.changeKey(w, distTo[w]); else pq.insert(w, distTo[w]); }
19
Dijkstra Similar idea is used in Dijkstra algorithm Dijkstra Digraph
Single-source shortest paths
20
Dijkstra General idea Compare to Eager Prim
After getting the shortest path from S to V, we want to update the distance from S to W. A previous path to W is through A, we do not not need to keep both the path from A and the path from V. We only keep the shorter one in the IndexPriority Queue. S A W Compare to Eager Prim In Eager Prim, <?, W> (distTo[w], edgeTo[w]) denotes the minimum-weight edge from the spanning tree to vertex W In Dijkstra, <?, W>. (distTo[w], edgeTo[w]) denotes the shortest path from start point S to vertex W V
21
Dijkstra General idea Y
In the IndexPriority queue, we keep track only one path to Y, only one path to W, and so on. Y S A W V
22
Dijkstra private void relax(DirectedEdge e) {
int v = e.from(), w = e.to(); if (distTo[w] > distTo[v] + e.weight()) { distTo[w] = distTo[v] + e.weight(); edgeTo[w] = e; if (pq.contains(w)) pq.changeKey(w, distTo[w]); else pq.insert(w, distTo[w]); } S A W V
23
Prim MST v.s. Dijkstra private void relax(DirectedEdge e) {
private void scan(EdgeWeightedGraph G, int v) { marked[v] = true; for (Edge e : G.adj(v)) { int w = e.other(v); if (marked[w]) continue if (e.weight() < distTo[w]) { distTo[w] = e.weight(); edgeTo[w] = e; if (pq.contains(w)) pq.changeKey(w, distTo[w]); else pq.insert(w, distTo[w]); } private void relax(DirectedEdge e) { int v = e.from(), w = e.to(); if (distTo[w] > distTo[v] + e.weight()) { distTo[w] = distTo[v] + e.weight(); edgeTo[w] = e; if (pq.contains(w)) pq.changeKey(w, distTo[w]); else pq.insert(w, distTo[w]); } In Prim, distTo[w] stores the minimum-weight crossing edge connecting MST vertex to non-MST vertex W In Dijsktra, distTo[w] stores the minimum-weight from single source point S to non-explored vertex W. This is a acummulated value.
Similar presentations
© 2024 SlidePlayer.com. Inc.
All rights reserved.