Homework 5 Solutions 1. Given an undirected graph G = (V, E), with V = {1, 2, · · · , n}. A set S ⊆ V is a dominating set if every vertex v ∈ V either belongs to S or is adjacent to a vertex in S. Given a graph, we would like to compute a dominating set of smallest size. Consider the following natural greedy algorithm that attempts to compute a dominating set. Given v ∈ V , let N (v) = {y ∈ V | hv, yi ∈ E} (a) Input G = (V, E). (b) Set D = ∅ (c) While V is not empty do • let v ∈ V be a vertex with largest degree. • Add v to D. • Remove v and all vertices in N (v) from G (and thus from V ). (d) Output D. Note: When we remove a vertex x from G, we remove x from V , and all edges that are incident on x from E. Using appropriate data structures, design an efficient implementation of the above algorithm and analyze/derive the runtime of your implementation. Express the run-time as a function of number of edges (m) and number of vertices (n). Your grade partly depends on efficiency. Remark. The above algorithm is a heuristic. It will not always produce a smallest dominating set. Think about graphs on which the above algorithm fails to produce a smallest dominating set. Ans. We use Max-Heap data structure. The heap will have tuples of the form hv, di. Where v is a vertex and d is the current degree of v. The following operations can be done in O(log n) time on Heaps: Extract Max, remove a tuple, update key of a tuple. Consider the following algorithm: (a) Input G = (V, E). (b) Set D = ∅. (c) Create a heap H of size n, where each entry if hv, d(v)i. Where d(v) is the degree of v. (d) While H is not empty do i. v = ExtractM ax(H). ii. Add v to D. 1 iii. For every hv, ui ∈ E A. For ever u, wi ∈ E • U pdateKey(w, d(w) − 1) B. Remove u from heap. (e) Output D. Time: Once a vertex is removed, it never re-enters the heap. Thus the total number of ExtractMax operations is at most n and Remove operations is at most n. Thus the total time taken for these operation is O(n log n). How many U pdateKey(w, d(w) − 1) are performed? Every time the algorithm looks at an edge hu, wi, we do a UpdateKey operation. How many times an edge hu, wi is considered? When we look at an edge hu, wi, the vertex u is removed from the heap. So we never look at hu, wi again. However, we may look at the edge hw, ui (since the graph is undirected). Thus each edge cause at most 2 UpdateKey operations. Thus the total time for UpdateKey operations is O(m log n). Thus the total time taken by the algorithm is O((m + n) log n). 2. Let G = (V, E) be an undirected graph with V = {1, 2, · · · , n}. Given a vertex x, let N (x) = {y ∈ V | hx, yi ∈ E} A subset S ⊆ V is called independent if for every pair of distinct vertices x, y from S, the following holds: N (x) ∩ N (y) = ∅ A set S ⊆ V is called maximal independent if S is independent and for every y ∈ / S, S ∪ {y} is not independent. • Design an algorithm that gets an undirected graph G = (V, E) and a subset S ⊆ V as input and determines if S is independent or not. You may assume V = {1, 2, · · · , n}. Derive the run-time of your algorithm. Part of your grade depends on the run-time. Ans. Let S = {u1 , u2 , · · · , u` }. We need to compute N (u1 ) ∩ N (u2 ) ∩ · · · N (u` ) if the above intersection is empty, then S is an independent set, otherwise it is not. We can compute the intersection efficiently using a boolean array. Consider the following algorithm. – Input: G = (V, E) and S. – Initialize a Boolean Array A of size n with all entries False. – For u ∈ S (a) For every hu, wi ∈ E ∗ if A[w] is true, then Return ”NOT INDEPENDENT”, else set A[w] to True. Run Time: The inner loop runs d(u) times. Each iteration of inner loop takes O(1) time. Thus the time P take by the inner loop is O(d(u)). Thus the total time for the nested loop is u∈S d(u) which is at most O(m). Time taken to initialize the boolean array is O(n). Thus the time is O(m + n). 2 • Design an algorithm that gets a graph G = (V, E) as input and outputs a maximal independent set of G. Derive the run-time of your algorithm. Your grade partly depends on the run-time. You may assume V = {1, 2, · · · , n}. Ans. We will use a greedy algorithm. Start with empty set S, and for every vertex v, we will place v in S if neighbors of v have an empty intersection with neighbors of vertices from S. Here is the algorithm. (a) Input G = (V, E). (b) S = ∅. (c) For v ∈ V i. Place v in S if S ∪ {v} is an independent set. Note that Step C (i) can be done in O(m + n) time. Thus a naive implementation of the above algorithm takes O(n(m + n)) time. We can make it efficient using good data structures. We maintain a set S, and a Boolean array named marked. Every vertex that is a neighbor of a vertex from S is marked. Consider the following algorithm. (a) (b) (c) (d) Input G = (V, E). S = ∅. M arked a Boolean Array of size n, all cells initialized to False. For i in the range 1 to n i. If i ∈ /S A. For every edge hi, ji ∈ E – If marked[j] is true; This means that a neighbor of i is a neighbor of a vertex from S. So i can not be placed into the independent set. Quit Loop; And go to next iteration of For loop. B. None of the neighbors of i is a neighbor of a vertex in S. Thus Place i in S and for every hi, ji ∈ E, set marked[j] = true. (e) Return S Note that the operations “ check if i ∈ S”, and “place i in S” can be done in O(1) time by storing S as Boolean array. P Inner loop takes O(d(i)) time. Thus the total total time taken by the outer loop is i d(i) which equals O(m). It takes O(n) time to create and initialize Boolean arrays corresponding to S and M arked. Thus total time is O(m + n). 3. Let M be a matrix of integers with n rows and m columns and let M [i, j] denote the entry in ith row and jth column. Both rows and columns are indexed from 1. A horizontal cut in M is a sequence [c1 , c2 , · · · , cm ] such that • For every i, 1 ≤ ci ≤ n • For 1 ≤ i ≤ m − 1, ci+1 ∈ {ci − 1, ci , ci + 1} Given a horizontal cut [c1 , c2 , · · · , cm ], its cost is M [c1 , 1] + M [c2 , 2] + · · · + M [cm , m]. A horizontal cut is a max-cost cut if its cost is at least the cost of any other horizontal cut. Give a dynamic programing algorithm, that gets a matrix M as input, and outputs the cost of the max-cost cut. Let C[i, j] be the cost of a max-cost horizontal cut that ends at M [i, j]. State the recurrence relation for C[i, j]. Based on this recurrence relation arrive at an iterative 3 algorithm. Derive the run time of your algorithm. Note that your algorithm need not output a max-cost cut, it suffices to output only its cost. Part of your grade depends on the run-time. Ans. Note that we can reach a cell M [i, j] from M [i−1, j −1], M [i, j −1] or from M [i+1, j −1]. Thus the cost of the best cut that ends at M [i, j] must one of the following: (a) Cost of the Best Cut that ends at M [i − 1, j − 1] plus M [i, j] (b) Cost of the Best Cut that ends at M [i, j − 1] plus M [i, j] (c) Cost of the Best Cut that ends at M [i + 1, j] plus M [i, j] More precisely, the cost of the best cut that ends at M [i, j] is the maximum of the above three. Thus C[i, j] = max{C[i − 1, j − 1], C[i, j − 1], C[i + 1, j − 1]} + M [i, j] This give following algorithm. Initialize a matrix C with all values to be negative infinity. Fill the first column as follows: C[i, 1] = M [i, 1] for i ∈ {1, · · · , n}. (a) Input M . (b) Create a n × m matrix C. (c) C[i, 1] = M [i, 1] for i ∈ {1, · · · , n}. (d) For j = 2 to m i. For i = 1 to n • C[i, j] = max{C[i − 1, j − 1], C[i, j − 1], C[i + 1, j − 1]} + M [i, j] (e) Compute the maximum of C[1, m], C[2, m], · · · , C[n, m] and return that value. Time taken is O(nm). 4. Let S = {x1 , x2 , · · · , xn } be a set of distinct non-negative integers. Give a dynamic programming algorithm that gets S as input and determines of there is a subset S 0 ⊆ S such that X X x= x x∈S 0 x∈S−S 0 Your algorithm must be based on an appropriately defined recurrence relation and must be iterative. Derive the run-time of your algorithm. Express run-time as a function of n and N , where N = x1 + x2 + · · · + xn . Part of your grade depends on the run-time. Ans. Let T [i, V ] to be true, if there is a subset A of {x1 , x2 , · · · , xn } such that the sum of integers in A equals V . Suppose that such a subset A exists. Now, of xi ∈ A, then there must be a subset B of {x1 , · · · , xi−1 } such that the sum of elements in B equals V − xn . Thus T [i − 1, V − xn ] must be true. Now, if xi ∈ / A, then A must be a subset of {x1 , · · · , xi−1 } and sum of elements in A equals V . Thus T [i − 1, V ] must be true. Thus we arrive at the following Recurrence T [i, V ] = T [i − 1, V − xn ] OR T [i − 1, V ] Based on this we arrive the following algorithm. 4 (a) Input {x1 , · · · , xn }. (b) Initialize a matrix M with n rows and N/2 + 1 columns with all cells ”False”. (c) For every j in [0, · · · , N/2], set M [1, j] = T if j equals x1 . Set M [1, 0] to true. (d) For i = 1 to n i. For j = 0 to N/2 • M [i, j] = M [i − 1, j − xi ] ORM [i − 1, j] (e) Return M [n, N/2]. The run time of the algorithm is O(nN ). GUIDE LINES: Same as before. 5