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