






Study with the several resources on Docsity
Earn points by helping other students or get them with a premium plan
Prepare for your exams
Study with the several resources on Docsity
Earn points to download
Earn points by helping other students or get them with a premium plan
An overview of the greedy method, with a focus on prim's algorithm for minimum spanning trees and dijkstra's algorithm for finding shortest paths in a graph. It includes the objective function, the concept of feasible and optimal solutions, the greedy method, and the implementation of prim's and dijkstra's algorithms. The document also discusses the correctness of these greedy algorithms and their applications in graph theory.
Typology: Study notes
1 / 10
This page cannot be seen from the preview
Don't miss anything!







1 10/24/
2 10/24/
3 10/24/
4 10/24/
5 10/24/
6 10/24/
7 10/24/
Knapsack Problems
Section 7.6 in text
Inputs:
n items, each with a weight w_i and a value v_i capacity of the knapsack, C
Output:
Fractions for each of the n items, x_I Chosen to maximize total profit but not to exceed knapsack capacity
8 10/24/
Two Types of Knapsack Problem
0/1 knapsack problem
Continuous knapsack problem
9 10/24/
Greedy Rule for Knapsack?
Build up a partial solution by choosing x_i for one item until knapsack is full (or no more items). Which item to choose?
There are several choices. Pick one and try on this:
What answer do you get?
The optimal answer is: (0, 1, 0.5), total=31. Can you verify this?
10 10/24/
Possible Greedy Rules for Knapsack
Build up a partial solution by choosing x_i for one item until knapsack is full (or no more items). Which item to choose? Maybe this: take as much as possible of the remaining item that has largest value, v_i Or maybe this: take as much as possible of the remaining items that has smallest weight, w_i Neither of these produce optimal values! The one that does “combines” these two approaches.
11 10/24/
Example Knapsack Problem
For this example:
n = 3, C = 20 weights = (18, 15, 10) values = (25, 24, 15)
Ratios = (25/18, 24/15, 15/10)
= (1.39, 1.6, 1.5)
The optimal answer is: (0, 1, 0.5)
12 10/24/
Minimum Spanning Tree
Problem: given a connected, undirected, weighted graph:
19 10/24/
Prim’s Algorithm
Run on example graph
MST-Prim(G, wt) init PQ to be empty; PQ.Insert(s, wt=0); parent[s] = NULL; while (PQ not empty) v = PQ.ExtractMin(); for each w adj to v if (w is unseen) { PQ.Insert(w, wt(v,w)); parent[w] = v; } else if (w is fringe && wt[v,w] < fringeWt(w)){ PQ.decreaseKey(w, wt[v,w]); parent[w] = v; } 20 10/24/
21 10/24/
Prim’s Algorithm
Run on example graph
MST-Prim(G, wt) init PQ to be empty; PQ.Insert(s, wt=0); parent[s] = NULL; while (PQ not empty) v = PQ.ExtractMin(); for each w adj to v if (w is unseen) { PQ.Insert(w, wt(v,w)); parent[w] = v; } else if (w is fringe && wt[v,w] < fringeWt(w)){ PQ.decreaseKey(w, wt[v,w]); parent[w] = v; } 22 10/24/
MST-Prim(G, wt) init PQ to be empty; PQ.Insert(s, wt=0); parent[s] = NULL; while (PQ not empty) v = PQ.ExtractMin(); for each w adj to v if (w is unseen) { PQ.Insert(w, wt(v,w)); parent[w] = v; } else if (w is fringe && wt[v,w] < fringeWt(w)){ PQ.decreaseKey(w, wt[v,w]); parent[w] = v; }
Prim’s Algorithm
s Pick a start vertex s
23 10/24/
MST-Prim(G, wt) init PQ to be empty; PQ.Insert(s, wt=0); parent[s] = NULL; while (PQ not empty) v = PQ.ExtractMin(); for each w adj to v if (w is unseen) { PQ.Insert(w, wt(v,w)); parent[w] = v; } else if (w is fringe && wt[v,w] < fringeWt(w)){ PQ.decreaseKey(w, wt[v,w]); parent[w] = v; }
Prim’s Algorithm
Red vertices have been removed from PQ
24 10/24/
MST-Prim(G, wt) init PQ to be empty; PQ.Insert(s, wt=0); parent[s] = NULL; while (PQ not empty) v = PQ.ExtractMin(); for each w adj to v if (w is unseen) { PQ.Insert(w, wt(v,w)); parent[w] = v; } else if (w is fringe && wt[v,w] < fringeWt(w)){ PQ.decreaseKey(w, wt[v,w]); parent[w] = v; }
Prim’s Algorithm
25 10/24/
MST-Prim(G, wt) init PQ to be empty; PQ.Insert(s, wt=0); parent[s] = NULL; while (PQ not empty) v = PQ.ExtractMin(); for each w adj to v if (w is unseen) { PQ.Insert(w, wt(v,w)); parent[w] = v; } else if (w is fringe && wt[v,w] < fringeWt(w)){ PQ.decreaseKey(w, wt[v,w]); parent[w] = v; }
Prim’s Algorithm
26 10/24/
MST-Prim(G, wt) init PQ to be empty; PQ.Insert(s, wt=0); parent[s] = NULL; while (PQ not empty) v = PQ.ExtractMin(); for each w adj to v if (w is unseen) { PQ.Insert(w, wt(v,w)); parent[w] = v; } else if (w is fringe && wt[v,w] < fringeWt(w)){ PQ.decreaseKey(w, wt[v,w]); parent[w] = v; }
Prim’s Algorithm
v
27 10/24/
MST-Prim(G, wt) init PQ to be empty; PQ.Insert(s, wt=0); parent[s] = NULL; while (PQ not empty) v = PQ.ExtractMin(); for each w adj to v if (w is unseen) { PQ.Insert(w, wt(v,w)); parent[w] = v; } else if (w is fringe && wt[v,w] < fringeWt(w)){ PQ.decreaseKey(w, wt[v,w]); parent[w] = v; }
Prim’s Algorithm
v
28 10/24/
MST-Prim(G, wt) init PQ to be empty; PQ.Insert(s, wt=0); parent[s] = NULL; while (PQ not empty) v = PQ.ExtractMin(); for each w adj to v if (w is unseen) { PQ.Insert(w, wt(v,w)); parent[w] = v; } else if (w is fringe && wt[v,w] < fringeWt(w)){ PQ.decreaseKey(w, wt[v,w]); parent[w] = v; }
Prim’s Algorithm
v
29 10/24/
Prim’s Algorithm
v
MST-Prim(G, wt) init PQ to be empty; PQ.Insert(s, wt=0); parent[s] = NULL; while (PQ not empty) v = PQ.ExtractMin(); for each w adj to v if (w is unseen) { PQ.Insert(w, wt(v,w)); parent[w] = v; } else if (w is fringe && wt[v,w] < fringeWt(w)){ PQ.decreaseKey(w, wt[v,w]); parent[w] = v; } 30 10/24/
Prim’s Algorithm
v
MST-Prim(G, wt) init PQ to be empty; PQ.Insert(s, wt=0); parent[s] = NULL; while (PQ not empty) v = PQ.ExtractMin(); for each w adj to v if (w is unseen) { PQ.Insert(w, wt(v,w)); parent[w] = v; } else if (w is fringe && wt[v,w] < fringeWt(w)){ PQ.decreaseKey(w, wt[v,w]); parent[w] = v; }
37 10/24/
MST-Prim(G, wt) init PQ to be empty; PQ.Insert(s, wt=0); parent[s] = NULL; while (PQ not empty) v = PQ.ExtractMin(); for each w adj to v if (w is unseen) { PQ.Insert(w, wt(v,w)); parent[w] = v; } else if (w is fringe && wt[v,w] < fringeWt(w)){ PQ.decreaseKey(w, wt[v,w]); parent[w] = v; }
Prim’s Algorithm
v
38 10/24/
Prim’s Algorithm
MST-Prim(G, wt)^ v init PQ to be empty; PQ.Insert(s, wt=0); parent[s] = NULL; while (PQ not empty) v = PQ.ExtractMin(); for each w adj to v if (w is unseen) { PQ.Insert(w, wt(v,w)); parent[w] = v; } else if (w is fringe && wt[v,w] < fringeWt(w)){ PQ.decreaseKey(w, wt[v,w]); parent[w] = v; }
39 10/24/
Prim’s Algorithm
v
MST-Prim(G, wt) init PQ to be empty; PQ.Insert(s, wt=0); parent[s] = NULL; while (PQ not empty) v = PQ.ExtractMin(); for each w adj to v if (w is unseen) { PQ.Insert(w, wt(v,w)); parent[w] = v; } else if (w is fringe && wt[v,w] < fringeWt(w)){ PQ.decreaseKey(w, wt[v,w]); parent[w] = v; } 40 10/24/
Cost of Prim’s Algorithm
(Assume connected graph)
Clearly it looks at every edge, so Ω(n+m)
Is there more? Yes, priority queue operations
ExtractMin called n times
descreaseKey could be called for each edge
41 10/24/
Worst Case
If all nodes connected to start, then size of PQ is n-
right away.
Note use of Big-Oh (not Big-Theta)
Could descreaseKey be called a lot?
42 10/24/
Priority Queue Costs and Prim’s
Simplest choice: unordered list PQ.ExtractMin() is just a “findMin”
PQ.decreaseKey() on a node finds it, changes it.
Conclusion: Easy to get Θ(n^2 )
43 10/24/
Called n times, so like Heap’s Construct: efficient!
44 10/24/
45 10/24/
46 10/24/
47 10/24/
v
MST-Prim(G, wt) init PQ to be empty; PQ.Insert(s, wt=0); parent[s] = NULL; while (PQ not empty) v = PQ.ExtractMin(); for each w adj to v if (w is unseen) { PQ.Insert(w, wt(v,w)); parent[w] = v; } else if (w is fringe && wt[v,w] < fringeWt(w)){ PQ.decreaseKey(w, wt[v,w]); parent[w] = v; } 48 10/24/
v
55 10/24/
MST-Prim(G, wt) init PQ to be empty; PQ.Insert(s, wt=0); parent[s] = NULL; while (PQ not empty){ v = PQ.ExtractMin(); for each w adj to v if (w is unseen) { PQ.Insert(w, wt(v,w)); parent[w] = v; } else if (w is fringe && wt[v,w] < fringeWt(w)){ PQ.decreaseKey(w, wt[v,w]); parent[w] = v; }
Reminder: Prim’s Algorithm
56 10/24/
dijkstra(G, wt, s) init PQ to be empty; PQ.Insert(s, dist=0); parent[s] = NULL; dist[s] = 0 ; while (PQ not empty) v = PQ.ExtractMin(); for each w adj to v if (w is unseen) { dist[w] = dist[v] + wt(v,w) PQ.Insert(w, dist[w] ); parent[w] = v; } else if (w is fringe && dist[v] + wt(v,w) < dist[w] ) { dist[w] = dist[v] + wt(v,w) PQ.decreaseKey(w, dist[w]); parent[w] = v; }
Dijkstra'Algorithm
57 10/24/
Notes on Dijkstra’s Algorithm
Use dist[] to store distances from start to any
fringe or tree node
Store and calculate using distances instead of
edge-weights (like in Kruskal’s MST)
What’s the output?
Tree captured in the parent[] array Shortest distance to each node in dist[] array Trace shortest path in reverse by using parent[] to move from target back to start node, s
58 10/24/
dijkstra(adj, start, parent) { n = adj.last for i = 1 to n { key[i] = } // key is a local array key[start] = 0; predecessor[start] = 0 // the following statement initializes the // container h to the values in the array key h.init(key,n) for i = 1 to n { v = h.min_weight_index() min_cost = h.keyval(v) v = h.del() ref = adj[v] while (ref != null) { w = ref.ver if (h.isin(w) && min_cost + ref.weight < h.keyval(w)) { predecessor[w] = v h.decrease(w, min_cost+ref.weight) } // end if ref = ref.next } // end while } // end for }
59 10/24/
Correctness of These Greedy
Algorithms
Recall that the greedy approach may or may
not guarantee an optimal result
Do these produce optimal solutions?
The min weight spanning tree? Kruskal’s, Prim’s The shortest path from s? Dijkstra’s
Answer: Yes, they do.
Proofs in the text Proofs by induction, also using proof by contradiction