Algorithm Design, Anal. & Imp., Homework 4 Solution Note: The solution is for your personal use for this course. You are not allowed to post the solution in public place. There could be mistakes in the solution; if you find any, let me know. Questions 1: Solve problem 24-2 (CLRS page 678) (3 + 5 + 7) (a). Say that x nests in y and y nests in z. This means that we can formulate a π mapping for both nesting relations such that: x πi < y i and y πj < z j Because all values of i and j are unique and drawn from the set 1 d we can find for each i a j such that i = π j. Then we have: x πi < y i = y πj < z j x πi < z j And we can find such a unique z j for every x πi. (b). Sort in non-decreasing order the d dimenson values within both x = (x 1, x 2 x d ) and y = (y 1, y 2 y d ). Compare x i and y i for every value of i = 1 to d. If x i < y i for all i then x nests within y. (c). Sort the d dimension values within each box B i. This takes O(d lg d) for every box, totalling to O(nd lg d) for the n boxes. For each possible pair of box (B i, B j ) check if B i nests in B j or if B j nests in B i. Each pair-comparison takes O(d) and there are O(n 2 ) pairs in total, so all nesting pair relations can be obtained in O(dn 2 ) steps. We create a graph with n nodes each representing one of the B i s. For each (B i, B j ) pair such that B i nests in B j we add a directed edge from B i to B j. This graph construction takes O(n 2 ) time. Now add a new vertices s to the graph, such that s has an outgoing edge to each vertices. Run topological sort on the resulting graph with s as the root vertex. Since V = O(n) for this graph, the runnning time for topological sort is O(n + n 2 ). Now consider all the vertices in topological order. For each vertex u examine its adjacency list and for each edge (u, v) anti-relax the edge as: 1
1 if d[v] < d[u] + w(u, v) 2 d[v] = d[u] + w(u, v) 3 π[v] = u This traversal takes O(E) = O(n 2 ) time. When the traversal terminates, find the vertex v with the largest d[v] value in O(n) time. Remove s from the graph and call PRINT-PATH on the vertex v. The overall running time of the algorithm is bounded by O(dn 2 + nd lg d). 2: Solve problem 23-3(a), and 23-3(b) (CLRS page 640) (8+7) (a). For graph G(V, E), T b is its Bottleneck Spanning Tree (BST), and T m is its MST. We claim that T b = T m. Proof : Assume that, T b T m ; also assume that the heaviest edge in T b is b with weight w b, and the heaviest edge in T m is m with weight w m. Case 1 (w b = w m ): The weight of the bottleneck edge in T b is equal to the weight of the heaviest edge in T m ; then, for the bottleneck problem, we can simply return T m instead of T b, as both have the same optimal value (weight of the heaviest edge). Then the bottleneck tree is an MST, and we are done with the proof. Case 2 (w b < w m ): Since, b is the heaviest edge in T b, and w b < w m, the edge m does not present in T b ; also weights of all the edges in T b is strictly smaller than w m. Now, consider the tree T m ; by removing the edge m from T m we obtain a forest with two trees. Since, m / T b, there must exist (at least) one edge, x, such that x T b and x / T m, and x connects the trees in the above forest to make another spanning tree of G, which is: T = T m {x} \ {m}; since weight of x is strictly smaller than w m, the tree T has smaller weight than the MST T m. Then T m is not an MST, we reach a contradiction, so this case can t happen. Case 3 (w b > w m ): In this case, the weight of the heaviest edge m in T m is strictly smaller than the weight of the bottleneck edge b in T b. Then T b is not a BST, because we have T m whose heaviest edge is smaller than the heaviest edge of T b. We reach another contradiction, so this case also cannot happen. Considering all the above cases, T b = T m (proved) (b). From the graph G, we remove all the edges that have weight higher than b. Then we run the Breadth-First-Search (BFS) on the modified graph to check if the graph is still connected. If it is, then the graph has a BST whose value is at most b, if the graph is not connected, it can t have a BST with a value b. The cost of BFS is linear, O(V + E). 3: Solve problem 34.5-7 (CLRS page 1101) (15) 2
The longest-simple-cycle problem is the problem of determining a simple cycle (no repeated vertices) of maximum length in a graph. Show that this problem is NP-complete. We first define the decision version of the longest-simple-cycle problem as below: LongestSimpleCycle(G, k): Given an undirected graph G and an integer k, does G has a simple cycle of length at least k. Now, we will show that LongestSimpleCycle(G, k) is N P-Complete. We will reduce a known N P-Complete problem, namely HamCycle(H) problem for this proof. The HamCycle(H) is defined as below: HamCycle(H): Given an undirected graph H does H has a Hamintonian cycle. LongestSimpleCycle(G, k) N P: Proof: Let (G, k) be an instance of LongestSimpleCycle. Given a certificate of proof y, which is a sequence of vertices, we can simply scan through the graph G in polynomial time to verify that y is a cycle, no vertex in y appears more than once, and length of y is k or higher. HamCycle(H) p LongestSimpleCycle(G, k): Proof: From an instance of HamCycle(H), we construct an instance LongestSimpleCycle(H, V ). The instrumentation is trivial and it can be done in constant (polynomial) time. Now we claim, the graph H(V, E) has a Hamintonian cycle, if and only if the length of its longest simple cycle is equal to V. The claim is correct, because if H(V, E) has a Hamiltonian cycle, that cycle is a simple path of length V. On the other hand, if H does not have a Hamiltonian cycle, the length of the longest simple in H must be strictly less than V. The above proofs conclude that the LongestSimpleCycle is N P-Complete. 4: Suppose you have a black-box subroutine to solve the decision version of the clique problem that is defined in Section 34.5.1. Give an algorithm that accepts an undirected graph G and returns a clique of maximum size. The running time of your algorithm should be polynomial in O( V ) and O( E ), considering that each query to the black-box takes O(1) time. (15) The decision version of clique problem takes as input two parameter, an undirected graph G(V, E) and a number k <= V. It returns yes if a clique of size k is present in graph G, no otherwise. Our assumption is that, this black-box operation takes O(1) time. Now, we give an algorithm which uses this black-box operation to return a clique of largest size. First, we find the size of the largest clique in a given graph G. For that we call black-box(g, i) where i = V. If black-box returns yes, we know that the size of largest clique is V or else we call black-box again but before that we decrement the possible largest clique size by 1 (black-box(g, i)) 3
with i = V 1. We repeat decrementing i and calling black-box, until we find the size of the largest clique. Thus, largest clique size = i, such that, black-box(g, i) = yes and (x>i) black-box(g, x) = no. Suppose k is the size of largest clique of graph G. For each v V we create G(V, E ) where V = V \ {v} and E = E \ {{(v, u)} {(u, v)} : u V } and check if the largest clique of new graph is also k. If yes we consider the new graph G instead of G for the next iteration. We return G(V, E) when V = k Find-max-clique(G(V, E)) 1 for i = V to 1: 2 if (black-box(g, i) == yes): 3 break; 4 tv = V 5 for each v tv : 6 G = (V, E ) where, V = V {v} and E = E {{(v, u)} {(u, v)} : u V } 7 if (black-box(g, i) == yes): 8 G = G 9 10 if V == k: 11 return G Complexity : Finding the size of largest clique can take at most V k call to black-box. Next from line 7 in each iteration we consider one node of the graph and no node is considered more than once. Consequently at most V call to black-box. All other computations are negligible with respect to black-box. Therefore, complexity of the algorithm is O( V ). 5: You are given a set of cities, along with the pattern of highways between them, in the form of an undirected graph G = (V, E). Each stretch of highway, e E connects two of the cities, and you know its length in miles, l e. You want to go from city s to city t. There s one problem: your car can only hold enough gas to cover L miles. There are gas stations in each city, but not between cities. Therefore, you can only take a route if every one of its edges has length l e L. a. Given the limitation on your car s fuel tank capacity, show how to determine in linear time whether there is a feasible route from s to t. (5) b. You are planning to buy a new car, and you want to know the minimum fuel tank capacity that is needed to travel from s to t. Give a O(E lg V ) algorithm to determine this. (5) Solution: a. Solution is trivial as removing all edges from the graph with length greater than L and then 4
performing a Depth-First-Search (DFS) starting from s and see if t can be reached (Running time of DFS is linear i.e., O(V + E) b. For this problem, we need to find a path from s to t, such that the largest edge-weight on the path is the smallest. We call it a bottleneck path from s to t. The maximum length edge on the bottleneck path is the bottleneck edge, and your car must have a fuel capacity to cover the distance of this bottleneck edge. Note that bottleneck path is not necessarily a shortest path. For example, assume, the shortest path distance from s to t has two edges with total weight of 10 (4 + 6), but there exist another path from s to t that has four edges with total weight of 11 (2 +3 + 3 + 3); clearly, the shortest path is not the bottleneck path, as the maximum edge weight in the second path is 3, which is smaller that the maximum edge weight in the first path (which is 6). To obtain a bottleneck path, we will modify the Dijkstra s algorithm as below: In Dijkstra s shortest path algorithm, for every vertex we have a field d, which is also the key field of the priority queue, Q. We replace the d field by another field called dist, such that u.dist stores the length of the bottleneck edge on a bottleneck path from s to u. The field, dist will be the key field of the priority queue in this solution. On initialization, s.dist = 0, and u.dist = for all u V \ {s}. To udpate u.dist, we need to modify the Relax subroutine as shown below. Then we call Dijkstra s algorithm by replacing the Initialize-Single-Source(G, s) with Initialize-Single-Source- Bottleneck(G, s). and also by replacing the Relax(u, v, w) with Relax-Bottleneck(u, v, w). Once Dijkstra terminates, the desired answer to the question is t.dist. Initialize-Single-Source-Bottleneck(G, s) 1 for each vertex v G.V 2 v.dist = 3 v.π = nil 4 5 s.dist = 0 Relax-Bottleneck(u, v.w) 1 if max(u.dist, w(u, v)) < v.dist 2 v.dist = max(u.dist, w(u, v)) 3 v.π = u Correctness Proof and Complexity: Bottleneck path holds optimal substructure property, i.e., for every vertex v, if u is the predecessor of v in a bottleneck path from s to v, the bottleneck edge from s to v is either the bottlenck edge on the path from s to u or the edge (u, v), whichever is larger. This is exactly what we implemented in the above Relax-Bottleneck subroutine. The complexity is O((E + V ) lg V ) = O(E lg V ) 5