Week 1,
Week 2,
Week 3,
Week 4,
(In-class Exam #1 Notes),
Week 5,
Week 6,
Week 7,
Week 8,
Week 9,
Week 10,
(In-class Exam #2 Notes),
Week 11,
Week 12,
Week 13,
(Final Exam Notes),
Week 14,
(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.
DFS-I(i, sol) if (i == n + 1) if (viable (sol)) return(cost(sol)) else return(INFINITY) else return(min(DFS-I(i + 1, sol), DFS-I(i + 1, sol U item[i])))
BFS-I() Q = {(1, empty set)} best = INFINITY while not empty(Q) (i, sol) = pop(Q) if (i == n + 1) if (viable(sol)) best = min(best, cost(sol)) else push(Q,(i + 1, sol)) push(Q,(i + 1, sol U item[i])) return(best)
Note that optimal leaf-solutions are circled and non-viable leaf-solutions are enclosed in dashed boxes.
DFS-IP(i, sol, best) if (not viable(sol)) or (best < cost(sol)) return(INFINITY) else if (i == n + 1) best = min(best, cost(sol)) return(cost(sol)) else return(min(DFS-IP(i + 1, sol, best), DFS-IP(i + 1, sol U item[i], best)))
BFS-IP() Q = {(1, empty set)} best = INFINITY while not empty(Q) (i, sol) = pop(Q) if (viable(sol) and (cost(sol) < best)) if (i == n + 1) best = min(best, cost(sol)) else push(Q,(i + 1, sol)) push(Q,(i + 1, sol U item[i])) 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.
Optimal Substructure? / \ / YES \ NO / \ D&C CST
FibR(n) if ((n == 1) || (n == 2)) return(1) else return(FibR(n - 1) + FibR(n - 2))
InitFibT(n,FibT) Allocate n-element table and assign to FibT FibT[1] = FibT[2] = 1 for (i = 3; i <= n; i++) FibT[i] = INFINITY FibM(n, FibT) if (FibT[n] == INFINITY) FibT[n] = FibM(n - 1, FibT) + FibM(n - 2, FibT) return(FibT[n])
FibI(n) if ((n == 1) || (n== 2)) return(1) else Allocate n-element table FibT FibT[1] = FibT[2] = 1 for (i = 3; i <= n; i++) FibT[i] = FibT[i - 1] + FibT[i - 2] 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).
I hope the above helps, and I wish you all the best of luck with this exam.
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 activites in the subset {a3, a9, a11} are all mutually compatible, but the largest such subset is {a1, a4, a8, a11}.
GREEDY_ACTIVITY-SELECTION(s, f) n = s.length A = {a1} k = 1 for m = 2 to n do if s(m) >= f(k) then A = A u {am} k = m return A
GENERIC-MST(G = (V,E,w)) F = (V, {}) for (i = 1; i <= |V| - 1; i++) Find a safe e in E for F = (V, E') F = (V, E' u {e}) return F
MST-KRUSKAL(G, w) A = {} for each vertex v in V do MAKE-SET(v) sort the edges in E in nondecreasing order by weight for each edge in (u,v) taken in nondecreasing order by weight do if FIND-SET(u) <> FIND-SET(v) then A = A u {(u,v)} UNION(u,v) return(A)
MST-PRIM(G,w,r) for each u in V do key[u] = INFTY pi[u] = nil key[r] = 0 Q = BUILD(V) while Q is not empty do u = EXTRACT-MIN(Q) for each v in adj[u] do if v in Q and w(u,v) < key[v] then pi[v] = u 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
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) |
BFS(G, s) for each vertex u in G - {s} do color[u] = white color[s] = gray Q = {} ENQUEUE(Q, s) while Q is not empty do u = DEQUEUE(Q) for each v in adj[u] do if color[v] = white then color[v] = gray ENQUEUE(Q,v) color[u] = black
BFS(G, s) for each vertex u in G - {s} do color[u] = white ** d[u] = INFTY ** pi[u] = nil color[s] = gray ** d[s] = 0 Q = {} ENQUEUE(Q, s) while Q is not empty do u = DEQUEUE(Q) for each v in adj[u] do if color[v] = white then color[v] = gray ** d[v] = d[u] + 1 ** pi[v] = u ENQUEUE(Q,v) color[u] = black
Initialize-Single-Source(G, s) for each vertex v in adj[v] do d[v] = INFTY pi[v] = nil d[s] = 0 Relax(u, v, w) if (d[v] > d[u] + w(u,v)) then d[v] = d[u] + w(u,v) pi[v] = u
Dijkstra(G, w, s) Initialize-Single-Source(G, s) S = {} Q = V[G] while Q is not empty do u = EXTRACT-MIN(Q) S = S u {u} for each vertex v in adj[u] do 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.
Dijkstra-Rewrite(G, w, s) for each u in V do d[u] = INFTY pi[u] = nil d[s] = 0 Q = V while Q not empty do u = EXTRACT-MIN(Q) for each v in adj[u] do if d[u] + w(u,v) < d[v] then d[v] = d[u] + w(u, v) pi[v] = u
Bellman-Ford(G, w, s) Initialize-Single-Source(G,s) for i = 1 to |V| - 1 do for each edge (u,v) in E do Relax(u, v, w) for each edge (u,v) in E do if d[v] > d[u] + w(u,v) then return FALSE return(TRUE)
Edges are relaxed in the following order in each relaxation-phase: (s,u). (s,x), (u,v), (u,x), (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}
EXTEND-SHORTEST-PATHS(L, W) n = rows[L] Create n x n matrix L' for i = 1 to n do for j = 1 to n do L'_ij = INFTY for k = 1 to n do L'_ij = min(L'_ij, L_ik + W_kj) return L'
SLOW-ALL-PAIRS-SHORTEST-PATHS(W) n = rows[W] L^(1) = W for m = 2 to n - 1 do L^(m) = EXTEND-SHORTEST-PATHS(L^(m - 1), W) return L^(n - 1)
FAST-ALL-PAIRS-SHORTEST-PATHS(W) n = rows[W] L^(1) = W m = 1 while m < n - 1 do L^(2 * m) = EXTEND-SHORTEST-PATHS(L^(m), L^(m)) m = 2 * m return L^(m)
FLOYD-WARSHALL(W) n = rows[W] D^(0) = W for k = 1 to n do Let D^(k) be a new n x n matrix for i = 1 to n do for j = 1 to n do D^(k)_ij = min(D^(k - 1)_ij, D^(k - 1)_ik + D^(k - 1)_kj) return D^(n)
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?
I hope the above helps, and I wish you all the best of luck with this exam.
APPROX-VERTEX-COVER(G) C = {} E' = E[G] while E' != {} do let (u,v) be an arbitrary edge of E' C = C U {u,v} remove from E' all edges with u or v as an endpoint return(C)
APPROX-KNAPSACK(U,s,v,B) Order items in u in decreasing ratio of value/size, i.e., v(u1)/s(u1) >- v(u2)/s(u2) >= ... >= v(un)/s(un) U' = {} for i = 1 to n do if size(U') + s(ui) <= B then U' = U' u {ui} max = 1 for i = 2 to n do if v(u_max) < v(ui) then max = i if (value(U') > v(u_max)) return(U') else 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?
FP-VERTEX-COVER(G,k) L = {({{},G)} VC = {} for i = 1 to k do for each item(S',G') in L do select arbitrary edge e = (u,v) in E' if G - {u} is empty then VC = VC u {S' u {u}} else L = L u {({S' u {u}}, G - {u})} if G - {v} is empty then VC = VC u {S' u {v}} else L = L u {({S' u {v}}, G - {v})} return(VC)
... Which brings us back, tired but hopefully wiser, to where we started in the first lecture of this course ...
Created: October 16, 2023
Last Modified: April 2, 2024