Week 1,
Week 2,
Week 3,
(In-class Exam #1 Notes),
Week 4.
Week 5,
Week 6,
Week 7,
(In-class Exam #2 Notes),
Week 8,
Week 9,
Week 10,
Week 11,
Week 12,
Week 13,
(end of diary)
Shortest Path (Unweighted) [Decision]
Input: A graph G = (V,E), two
vertices u and v in V, and a positive integer k.
Question: Is there a path P in G from u to v such
that the number of edges in P is <= k?
Shortest Path (Unweighted) [Evaluation]
Input: A graph G = (V,E) and two
vertices u and v in V.
Output: The length of the path in G from u to v
with the smallest possible number of edges.
Shortest Path (Unweighted) [Solution]
Input: A graph G = (V,E) and two
vertices u and v in V.
Output: A path P in G from u to v such that
the number of edges in P is the smallest possible.
Shortest Path (Unweighted)
Input: A graph G = (V,E) and two
vertices u and v in V.
Output: A path P in G from u to v such that
the number of edges in P is the smallest possible.
Shortest Path (Weighted)
Input: An edge-weighted graph G = (V,E,W) and two
vertices u and v in V.
Output: A path P in G from u to v such that
the sum of the weights of the edges in P is the
smallest possible.
Longest Path (Unweighted)
Input: A graph G = (V,E) and two
vertices u and v in V.
Output: A path P in G from u to v such that
the number of edges in P is the largest possible.
Longest Path (Weighted)
Input: An edge-weighted graph G = (V,E,W) and two
vertices u and v in V.
Output: A path P in G from u to v such that
the sum of the weights of the edges in P is the
largest possible.
Vertex Cover
Input: An undirected graph G = (V,E).
Output: A subset V' \subseteq V such that
for all edges (u,v) \in E, at least one of u and v is
in V', and the size of V' is the smallest possible.
| C(x) | T(n) | T(n) | O(g(n)) | |||||
| Actual | Abstract | (Exact) | Worst-Case | Asymptotic | ||||
| Running | -----> | Running | -----> | Time | -----> | Time | -----> | Worst-Case |
| Time | Time | Complexity | Complexity | Time | ||||
| Complexity | ||||||||
| Instruction | Input Size | Worst-Case | Asymptotic | |||||
| Counts | Selection | Notation |
Which method you use depends on the intricacy of the given algorithm.
This allows (to a degree) for instructions whose running-times differ by a constant multiplicative factor on different machines.
P1(n): blah blah blah x = P2(n) blah blah blah output zThis has several implications:
The former is the reason why we create efficient libraries of commonly-called algorithms; as we shall see in the final section of this course, the latter is the basis for showing that a problem does not have an efficient algorithm.
Longest common subsequence (LCS)
Input: Two strings s, s' over an alphabet
Sigma.
Output: All strings s'' over Sigma such that s'' is
a subsequence of both s and s' and the length of
s'' is of is maximized over the solution space.
1. DFS-I(i, sol) 2. if (i == n + 1) 3. if (viable (sol)) 4. return(cost(sol)) 5. else 6. return(INFINITY) 7. else 8. return(min(DFS-I(i + 1, sol), 9. DFS-I(i + 1, sol U item[i])))
1. BFS-I()
2. Q = {(1, empty set)}
3. best = INFINITY
4. while not empty(Q)
5. (i, sol) = pop(Q)
6. if (i == n + 1)
7. if (viable(sol))
8. best = min(best, cost(sol))
9. else
10. push(Q,(i + 1, sol))
11. push(Q,(i + 1, sol U item[i]))
12. return(best)
Note that optimal leaf-solutions are circled and non-viable leaf-solutions are enclosed in dashed boxes.
1. DFS-IP(i, sol, best) 2. if (not viable(sol)) or (best < cost(sol)) 3. return(INFINITY) 4. else if (i == n + 1) 5. best = min(best, cost(sol)) 6. return(cost(sol)) 7. else 8. return(min(DFS-IP(i + 1, sol, best), 9. DFS-IP(i + 1, sol U item[i], best)))
1. BFS-IP()
2. Q = {(1, empty set)}
3. best = INFINITY
4. while not empty(Q)
5. (i, sol) = pop(Q)
6. if (viable(sol) and (cost(sol) < best))
7. if (i == n + 1)
8. best = min(best, cost(sol))
9. else
10. push(Q,(i + 1, sol))
11. push(Q,(i + 1, sol U item[i]))
12. return(best)
Note that optimal solutions are circled and non-viable solutions are enclosed in dashed boxes.
Note that optimal solutions are circled and non-viable (non-potential optimal) solutions are enclosed in dashed (dotted) boxes.
Note that all nodes in the tree corresponding to models that make the given sentence true have been circled.
I hope the above helps, and I wish you all the best of luck with this exam.
Optimal Substructure? / \ / YES \ NO / \ D&C CST
1. FibR(n) 2. if ((n == 1) || (n == 2)) 3. return(1) 4. else 5. return(FibR(n - 1) + FibR(n - 2))
1. InitFibT(n,FibT) 2. Allocate n-element table and assign to FibT 3. FibT[1] = FibT[2] = 1 4. for (i = 3; i <= n; i++) 5. FibT[i] = INFINITY 6. FibM(n, FibT) 7. if (FibT[n] == INFINITY) 8. FibT[n] = FibM(n - 1, FibT) + 9. FibM(n - 2, FibT) 10. return(FibT[n])
1. FibI(n) 2. if ((n == 1) || (n== 2)) 3. return(1) 4. else 5. Allocate n-element table FibT 6. FibT[1] = FibT[2] = 1 7. for (i = 3; i <= n; i++) 8. FibT[i] = FibT[i - 1] + FibT[i - 2] 9. return(FibT[n])
Observe that the reconstructed LCS is bab (matching characters in s and s' as well as the traceback path to derive this subsequence are indicated by circled elements).
There are many other types of alignment, e.g., pairwise semi-global, multi-sequence alignment (see Sections 11 and 14 of Gusfield (1997)).
Note that diagonal backpointers go back in the row and not necessarily to that backpointer's origin-cell. Observe that the above yields the optimal solution {u1,u2} with value 5.
Optimal
Substructure
AND
Independent
Subproblems?
/ \
/ YES \ NO
/ \
Repeated CST
Subproblems?
/ \
/ YES \ NO
/ \
DP D&C
i | 1 2 3 4 5 6 7 8 9 10 11 ------------------------------------------------ si | 1 3 0 5 3 5 6 8 8 2 12 fi | 4 5 6 7 9 9 10 11 12 14 16The activities in the subset {a3, a9, a11} are all mutually compatible, but the largest such subset is {a1, a4, a8, a11}.
1. ActSelGI(s, f)
2. n = s.length
3. A = {a1}
4. k = 1
5. for m = 2 to n do
6. if s(m) >= f(k) then
7. A = A u {am}
8. k = m
9. return A
1. MSTGen(G = (V,E,w))
2. F = (V, {})
3. for (i = 1; i <= |V| - 1; i++)
4 Find a safe e in E for F = (V, E')
5. F = (V, E' u {e})
6. return F
1. MSTKruskal(G, w)
2. A = {}
3. for each vertex v in V do
4. MAKE-SET(v)
5. sort the edges in E in nondecreasing order by weight
6. for each edge in (u,v) taken in nondecreasing order by weight do
7. if FIND-SET(u) <> FIND-SET(v) then
8. A = A u {(u,v)}
9. UNION(u,v)
10. return(A)
1. MSTPrim(G,w,r) 2. for each u in V do 3. key[u] = INFTY 4. pi[u] = nil 5. key[r] = 0 6. Q = BUILD(V) 7. while Q is not empty do 8. u = EXTRACT-MIN(Q) 9. for each v in adj[u] do 10. if v in Q and w(u,v) < key[v] then 11. pi[v] = u 12. key[v] = w(u,v)
That being said, the examples given above are useful as they show the intimate relationship between dynamic programming and greedy algorithms.
Optimal
Substructure
AND
Independent
Subproblems?
/ \
/ YES \ NO
/ \
Repeated CST
Subproblems?
/ \
/ YES \ NO
/ \
Greedy D&C
Choice?
/ \
/ YES \ NO
/ \
Greedy DP
1. FracKnap(U)
2. U' = items in U sorted in descending order by v(u_i)/(s(u_i)
3. leftB = B
4. Knap = {}
5. i = 1
6. while i <= |U'| and leftB >= s(u'i) do
7. Knap = Knap u {all u'i)}
8. leftB = leftB - s(u'i)
9. i = i + 1
10. if leftB > 0 and i <= |U'| then
11. Knap = Knap u {leftB/s(u'i) u'i}
12. return Knap
I hope the above helps, and I wish you all the best of luck with this exam.
| Data Structure | Time Complexity (Worst Case) | |||
| MAKE-SET | FIND-SET | UNION | Kruskal's Algorithm |
|
| List (naive) | O(1) | O(n) | O(1) | O(|E||V|) |
| List (rep-ptr) | O(1) | O(1) | O(n) | O(|E||V|) |
| Forest (naive) | O(1) | O(n) | O(1) | O(|E||V|) |
| Forest (rep-ptr) | O(1) | O(1) | O(n) | O(|E||V|) |
| Forest (UR + PC) | O(1) | O(1) | O(1) | O(|E| log |V|) |
Note that the O(1) runtimes of Kruskal's algorithm relative to the forest implementation of the disjoint sets abstract data type under the Union-by-Rank (UR) and path-compression (PC) heuristics are actually averages over sequences of operations and requires somewhat intricate proofs of correctness (Section 21.4).
| Data Structure | Time Complexity (Worst Case) | |||
| BUILD | EXTRACT- MIN |
DECREASE- KEY |
Prim's Algorithm |
|
| Array (Unsorted) | O(n) | O(n) | O(n) | O(|E||V|) |
| Linked list (Unsorted) | O(n) | O(n) | O(n) | O(|E||V|) |
| Array (Sorted) | O(n log n) | O(n) | O(n) | O(|E||V|) |
| Linked list (Sorted) | O(n log n) | O(1) | O(n) | O(|E||V|) |
| Search tree | O(n) | O(n) | O(n) | O(|E||V|) |
| Balanced search tree | O(n) | O(log n) | O(log n) | O(|E| log |V|) |
| Binary heap | O(n) | O(log n) | O(log n) | O(|E| log |V|) |
| Data Structure | Time Complexity (Worst Case) | |
| NEXT-ADJ | ADJ | |
| Adjacency List | O(1) | O(|V|) |
| Adjacency Matrix | O(|V|) | O(1) |
1. BFSBasic(G, s)
2. for each vertex u in G - {s} do
3. color[u] = white
4. color[s] = gray
5. Q = {}
6. ENQUEUE(Q, s)
7. while Q is not empty do
8. u = DEQUEUE(Q)
9. for each v in adj[u] do
10. if color[v] = white then
11. color[v] = gray
12. ENQUEUE(Q,v)
13. color[u] = black
Process vertices and vertex adjacencies in alkphabetical order.
1. BFSFull(G, s)
2. for each vertex u in G - {s} do
3. color[u] = white
4. ** d[u] = INFTY
5. ** pi[u] = nil
6. color[s] = gray
7. ** d[s] = 0
8. Q = {}
9. ENQUEUE(Q, s)
10. while Q is not empty do
11. u = DEQUEUE(Q)
12. for each v in adj[u] do
13. if color[v] = white then
14. color[v] = gray
15. ** d[v] = d[u] + 1
16. ** pi[v] = u
17. ENQUEUE(Q,v)
18. color[u] = black
Process vertices and vertex adjacencies in alkphabetical order.
1. DFS(G) 2. for each vertex u in V(G) do 3. color[u] = white 4. for each vertex u in V(G) do 5. if color[u] = white then 6. DFS-visit(u) 7. DFS-visit(u) 8. color[u] = gray 9. for each v in adj[u] do 10. if color[v] = white 11. DFS-visit(v) 12. color[u] = black
Process vertices and vertex adjacencies in alkphabetical order.
1. DFS(G) 2. for each vertex u in V(G) do 3. color[u] = white 4. ** pi[u] = nil 5. ** time = 0 6. for each vertex u in V(G) do 7. if color[u] = white then 8. DFS-visit(u) 9. DFS-visit(u) 10. color[u] = gray 11. ** time = time + 1 12. ** d[u] = time 13. for each v in adj[u] do 14. if color[v] = white 15. ** pi[v] = u 16. DFS-visit(v) 17. color[u] = black 18. ** time = time + 1 19. ** f[u] = time
Process vertices and vertex adjacencies in alkphabetical order.
1. InitSingleSource(G, s) 2. for each vertex v in adj[v] do 3. d[v] = INFTY 4. pi[v] = nil 5. d[s] = 0 6. Relax(u, v, w) 7. if (d[v] > d[u] + w(u,v)) then 8. d[v] = d[u] + w(u,v) 9. pi[v] = u
1. Dijkstra(G, w, s)
2. Initialize-Single-Source(G, s)
3. S = {}
4. Q = V[G]
5. while Q is not empty do
6. u = EXTRACT-MIN(Q)
7. S = S u {u}
8. for each vertex v in adj[u] do
9. Relax(u, v, w)
Part (a) shows the initial state of the graph and subsequent parts show the graph after a particular vertice's adjacencies have been relaxed. Black vertices are fully relax-processed and the shaded vertex is the vertex whose adjacencies will be relaxed in the next part. d-values are written next to vertex names and pi-values are implicit in the thick edges.
1. DijkstraRewrite(G, w, s) 2. for each u in V do 3. d[u] = INFTY 4. pi[u] = nil 5. d[s] = 0 6. Q = V 7. while Q not empty do 8. u = EXTRACT-MIN(Q) 9. for each v in adj[u] do 10. if d[u] + w(u,v) < d[v] then 11. d[v] = d[u] + w(u, v) 12. pi[v] = u
1. BellmanFord(G, w, s) 2. Initialize-Single-Source(G,s) 3. for i = 1 to |V| - 1 do 4. for each edge (u,v) in E do 5. Relax(u, v, w) 6. for each edge (u,v) in E do 7. if d[v] > d[u] + w(u,v) then 8. return FALSE 9. return(TRUE)
Edges are relaxed in the following order in each relaxation-phase: (s,u). (s,x), (u,v), (u,x), (u,y), (v,y), (x,u), (x,y), (y,s), (y,v). d-values are written next to vertex names and pi-values are implicit in the thick edges.
| Wi,j= { | 0 | if i == j | w(i,j) | if i <> j and (i,j) in E | INFTY | if i <> j and (i,j) not in E |
| L(0)i,j= { | 0 | i == j |
| INFTY | i <> j |
| L(m)i,j = min1 <= k <= |V|{ | L(m-1)i,k + Wk,j | } |
D(0)i,j = Wi,j
D(m)i,j = min {
D (m-1)i,j ,
D (m-1)i,m +
D (m-1)m,j}
1. ExtendShortestPaths(L, W) 2. n = rows[L] 3. Create n x n matrix L' 4. for i = 1 to n do 5. for j = 1 to n do 6. L'_ij = INFTY 7. for k = 1 to n do 8. L'_ij = min(L'_ij, L_ik + W_kj) 9. return L'
1. AllPairsShortestPathsSlow(W) 2. n = rows[W] 3. L^(1) = W 4. for m = 2 to n - 1 do 5. L^(m) = ExtendShortestPaths(L^(m - 1), W) 6. return L^(n - 1)
1. AllPairsShortestPathsFast(W) 2. n = rows[W] 3. L^(1) = W 4. m = 1 5. while m < n - 1 do 6. L^(2 * m) = EXTEND-SHORTEST-PATHS(L^(m), L^(m)) 7. m = 2 * m 8. return L^(m)
1. APSPFloydWarshall(W) 2. n = rows[W] 3. D^(0) = W 4. for k = 1 to n do 5. Let D^(k) be a new n x n matrix 6. for i = 1 to n do 7. for j = 1 to n do 8. D^(k)_ij = min(D^(k - 1)_ij, 9. D^(k - 1)_ik + 10. D^(k - 1)_kj) 11. return D^(n)
.... or maybe nobody is, e.g.,
... or perhap there really isn't a polynomial-time algorithm for that problem, e.g.,
In this last case, the problem is said to be (polynomial-time) intractable,
Polynomial-time solvability
<-------------
A reduces to B reduces to C
------------->
Polynomial-time unsolvability
Vertex Cover (VC)
Input: An undirected graph G = (V,E) and an integer k > 0.
Question: Is there a vertex cover of G of size at most k,
i.e, is there a subset V' \subseteq V such that |V'| <= k
and for all edges (u,v) \in E, at least one of u and v is in V'?
Vertex Cover Cost (VC-C)
Input: An undirected graph G = (V,E).
Output:} The size of the smallest vertex cover of G.
Vertex Cover Example (VC-E)
Input: An undirected graph G = (V,E).
Output: One of the smallest vertex covers of G.
Clique
Input: An undirected graph G = (V,E) and an integer k > 0.
Question: Is there a clique in G of size at least k, i.e.,
is there a subset V' \subseteq V, |V'| >= k, such that for all
u, v \in V', (u,v) \in E?
Subset sum (SS)
Input: A set S of integers and an integer k \geq 0.
Question: Is there a subset S' of S whose elements sum to k?
Steiner tree in graphs (STG)
Input: An undirected graph G = (V,E), a set V' \subseteq V,
and an integer k > 0.
Question: Is there a tree in G that connects all vertices in
V' and contains at most k edges?
VERTEX-COVER-DECISION(G, k)
if (VERTEX-COVER-COST(G) <= k) then
return(TRUE)
else
return(FALSE)
VERTEX-COVER-COST(G)
k = 1
while not VERTEX-COVER-DECISION(G,k) do
k = k + 1
return(k)
VERTEX-COVER-DECISION(G, k)
if (cost(VERTEX-COVER-EXAMPLE(G))) <= k then
return(TRUE)
else
return(FALSE)
VERTEX-COVER-EXAMPLE(G)
min_cost = 1
while not VERTEX-COVER-DECISION(G,min_cost) do
min_cost = min_cost + 1
k = min_cost
S = {}
G' = G
while |S| < min_cost do
for each vertex v' in V' do
G'' = (V' u {x}, E' u {(v',x)})
if (VERTEX-COVER-DECISION(G'',k)) then
S = S u {v'}
G' = G' - {v'}
k = k - 1
break
return(S)
0/1 Knapsack (decision version) (01KN)
Input: A set U of items, an item-size
function s(), an item-value function v(), and
positive integer B and k.
Question: Is there a subsets U' of U such that the
sum of the sizes of the items in U' is less
than or equal to B and the sum of the values of
the items in U' is at least k?
CNF Satisfiability
Input: A CNF formula F.
Question: Is there a satisfying assignment
for F, i.e., an assignment of values to
the variables of F that make F evaluate to
True?
3-CNF Satisfiability
Input: A 3-CNF formula F.
Question: Is there a satisfying assignment
for F?
Circuit Satisfiability
Input: A circuit C.
Question: Is there a set of input-values for
C that
makes C output true on its output line?
General Satisfiability
Input: A combinational logic formula F.
Question: Is there a satisfying assignment
for F?
1. VCoverApprox(G)
2. C = {}
3. E' = E[G]
4. while E' != {} do
5. let (u,v) be an arbitrary edge of E'
6. C = C U {u,v}
7. remove from E' all edges with u or v as an endpoint
8. return(C)
1. 01KNApprox(U,s,v,B)
2. Order items in u in decreasing ratio of value/size, i.e.,
v(u1)/s(u1) >- v(u2)/s(u2) >= ... >= v(un)/s(un)
3. U' = {}
4. for i = 1 to n do
5. if size(U') + s(ui) <= B then
6. U' = U' u {ui}
7. max = 1
8. for i = 2 to n do
9. if v(u_max) < v(ui) then
10. max = i
11. if (value(U') > v(u_max))
12. return(U')
13. else
14. return({u_max})
3-D Robot Motion Planning (3DRMP)
Input: A jointed robot R, a set of obstacles
O embedded in some 3-D environment E,
and initial and final positions p_I
and p_F of R in E.
Question: Is there a sequence of robot
motions that move R from p_I to p_F
without colliding with any obstacles
in O?
1. VCoverFP(G,k)
2. L = ({},G)
3. VC = {}
4. for i = 1 to k do
5. for each item(S',G') in L do
6. select arbitrary edge e = (u,v) in E'
7. if G - {u} is empty then
8. VC = VC u {S' u {u}}
9. else
10. L = ({S' u {u}}, G - {u})
11. if G - {v} is empty then
12. VC = VC u {S' u {v}}
13. else
14. L = ({S' u {v}}, G - {v})
15. return(VC)
... Which brings us back, tired but hopefully wiser, to where we started in the first lecture of this course ...
Created: July 7, 2026
Last Modified: November 10, 2026