04
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<br>
05
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);
}
} private void scan(EdgeWeightedGraph G, int v) {
marked[v] = true;
for (Edge e : G.adj(v))
if (!marked[e.other(v)]) pq.insert(e);
} W V After putting V into to MST, both of the edges associated with W are in the priority queue<br>
06
Lazy Prim Example D B A C G E F D B A C G E F Min PQ
(A, D): 1
(A, B): 2
(A, G): 3
(A, E): 4
(A, C): 5 1 2 3 4 5 2 2 3 4<br>
07
Lazy Prim Example D B A C G E F D B A C G E F Min PQ
(A, D): 1
(A, B): 2
(D, E): 2
(A, G): 3
(A, E): 4
(B, D): 4
(A, C): 5 1 2 3 4 5 2 2 3 4<br>
08
Lazy Prim Example D B A C G E F D B A C G E F 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 1 2 3 4 5 2 2 3 4<br>
09
Lazy Prim Example D B A C G E F D B A C G E F 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 1 2 3 4 5 2 2 3 4<br>
10
Lazy Prim Example D B A C G E F D B A C G E F 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 1 2 3 4 5 2 2 3 4<br>
11
Lazy Prim Example D B A C G E F D B A C G E F 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 1 2 3 4 5 2 2 3 4<br>
12
Lazy Prim Example D B A C G E F D B A C G E F 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 1 2 3 4 5 2 2 3 4<br>
13
Think about Eager Prim Lazy 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?<br>
14
Think about Eager Prim D B A C G E F D B A C G E F Min PQ
(A, D): 1
(A, B): 2
(D, E): 2
(A, G): 3
(A, E): 4
(B, D): 4
(A, C): 5 1 2 3 4 5 2 2 3 4 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?<br>
15
Lazy Prim v.s. Eager Prim A W V After putting V into to MST, both of the edges associated with W are in the priority queue 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])<br>
16
Lazy Prim v.s. Eager Prim A W V After putting V into to MST, both of the edges associated with W are in the priority queue 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.<br>
17
Lazy Prim v.s. Eager Prim A W V 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]);
}
}
} Eager Prim keeps only the smaller of <A,W> and <V,W> in the IndexPriorityQueue<br>
18
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;
for (int v = 0; v < G.V(); v++)
if (!marked[v]) prim(G, v);
assert check(G);
} 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);
}
} 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]);
}
}
}<br>
19
Dijkstra Similar idea is used in Dijkstra algorithm
Dijkstra
Digraph
Single-source shortest paths<br>
20
Dijkstra S A V W General idea
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. 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<br>
21
Dijkstra S A V W Y General idea
In the IndexPriority queue, we keep track only one path to Y, only one path to W, and so on.<br>
22
Dijkstra S A V 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]);
}
}<br>
23
Prim MST v.s. Dijkstra 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.<br>