Assignment 4. CSci 3110: Introduction to Algorithms. Sample Solutions

Similar documents
2. (25%) Suppose you have an array of 1234 records in which only a few are out of order and they are not very far from their correct positions. Which

Solutions to the Midterm Practice Problems

CPSC 320 (Intermediate Algorithm Design and Analysis). Summer Instructor: Dr. Lior Malka Final Examination, July 24th, 2009

CMSC 451: Lecture 7 Greedy Algorithms for Scheduling Tuesday, Sep 19, 2017

CS Analysis of Recursive Algorithms and Brute Force

/633 Introduction to Algorithms Lecturer: Michael Dinitz Topic: Dynamic Programming II Date: 10/12/17

COMP 555 Bioalgorithms. Fall Lecture 3: Algorithms and Complexity

Announcements. CompSci 102 Discrete Math for Computer Science. Chap. 3.1 Algorithms. Specifying Algorithms

Midterm Exam. CS 3110: Design and Analysis of Algorithms. June 20, Group 1 Group 2 Group 3

(a) Write a greedy O(n log n) algorithm that, on input S, returns a covering subset C of minimum size.

University of Toronto Department of Electrical and Computer Engineering. Final Examination. ECE 345 Algorithms and Data Structures Fall 2016

CS325: Analysis of Algorithms, Fall Final Exam

Lecture 6 September 21, 2016

Algorithm Design and Analysis

Homework #2 Solutions Due: September 5, for all n N n 3 = n2 (n + 1) 2 4

Discrete Mathematics: Logic. Discrete Mathematics: Lecture 17. Recurrence

NATIONAL UNIVERSITY OF SINGAPORE CS3230 DESIGN AND ANALYSIS OF ALGORITHMS SEMESTER II: Time Allowed 2 Hours

Algorithm Design Strategies V

Chapter 4. Greedy Algorithms. Slides by Kevin Wayne. Copyright 2005 Pearson-Addison Wesley. All rights reserved.

Mathematical Induction

Solutions. Problem 1: Suppose a polynomial in n of degree d has the form

CSE 202 Homework 4 Matthias Springer, A

Greedy Algorithms My T. UF

Discrete Math, Spring Solutions to Problems V

Lecture 5: Loop Invariants and Insertion-sort

0 1 d 010. h 0111 i g 01100

Searching Algorithms. CSE21 Winter 2017, Day 3 (B00), Day 2 (A00) January 13, 2017

Dynamic Programming. Credits: Many of these slides were originally authored by Jeff Edmonds, York University. Thanks Jeff!

Algorithms and Data Structures 2016 Week 5 solutions (Tues 9th - Fri 12th February)

Another Proof By Contradiction: 2 is Irrational

Recursion: Introduction and Correctness

IS 709/809: Computational Methods for IS Research. Math Review: Algorithm Analysis

With Question/Answer Animations

Matrix Multiplication

Data structures Exercise 1 solution. Question 1. Let s start by writing all the functions in big O notation:

Fall 2017 Test II review problems

Data Structures in Java

Shortest paths with negative lengths

Undirected Graphs. V = { 1, 2, 3, 4, 5, 6, 7, 8 } E = { 1-2, 1-3, 2-3, 2-4, 2-5, 3-5, 3-7, 3-8, 4-5, 5-6 } n = 8 m = 11

NOTE: You have 2 hours, please plan your time. Problems are not ordered by difficulty.

Chapter 4. Greedy Algorithms. Slides by Kevin Wayne. Copyright 2005 Pearson-Addison Wesley. All rights reserved.

Data Structures and Algorithms (CSCI 340)

Michael Kaiser Assignment 1 Comp 510 Fall 2012

Activity selection. Goal: Select the largest possible set of nonoverlapping (mutually compatible) activities.

Homework 1 Submission

DM507 - Algoritmer og Datastrukturer Project 1

ECOM Discrete Mathematics

CS60007 Algorithm Design and Analysis 2018 Assignment 1

CSCI 3110 Assignment 6 Solutions

NOTES ON OCT 9, 2012

1 Some loose ends from last time

Contents Lecture 4. Greedy graph algorithms Dijkstra s algorithm Prim s algorithm Kruskal s algorithm Union-find data structure with path compression

Advanced Analysis of Algorithms - Midterm (Solutions)

b + O(n d ) where a 1, b > 1, then O(n d log n) if a = b d d ) if a < b d O(n log b a ) if a > b d

Turing Machines, diagonalization, the halting problem, reducibility

CSC236H Lecture 2. Ilir Dema. September 19, 2018

6.841/18.405J: Advanced Complexity Wednesday, February 12, Lecture Lecture 3

CS481: Bioinformatics Algorithms

Ma/CS 6a Class 25: Partitions

COM S 330 Homework 08 Solutions. Type your answers to the following questions and submit a PDF file to Blackboard. One page per problem.

Analysis of Algorithms I: Asymptotic Notation, Induction, and MergeSort

Dynamic Programming( Weighted Interval Scheduling)

Computer Science & Engineering 423/823 Design and Analysis of Algorithms

3.1 Asymptotic notation

Another way of saying this is that amortized analysis guarantees the average case performance of each operation in the worst case.

1 Assembly Line Scheduling in Manufacturing Sector

Midterm Exam 2 Solutions

Two Dynamic Programming Methodologies in Very Large Scale Neighborhood Search Applied to the Traveling Salesman Problem

Combinatorial Optimization

CS 161: Design and Analysis of Algorithms

Algorithms: Lecture 12. Chalmers University of Technology

Lecture 7: Dynamic Programming I: Optimal BSTs

Analysis of Algorithms - Using Asymptotic Bounds -

Tute 10. Liam O'Connor. May 23, 2017

And, even if it is square, we may not be able to use EROs to get to the identity matrix. Consider

CSE 20 DISCRETE MATH WINTER

1. Problem I calculated these out by hand. It was tedious, but kind of fun, in a a computer should really be doing this sort of way.

Divide-Conquer-Glue Algorithms

Recap & Interval Scheduling

CS173 Running Time and Big-O. Tandy Warnow

Heaps Induction. Heaps. Heaps. Tirgul 6

1 Efficient Transformation to CNF Formulas

Lecture 2: Divide and conquer and Dynamic programming

CS361 Homework #3 Solutions

Input Decidable Language -- Program Halts on all Input Encoding of Input -- Natural Numbers Encoded in Binary or Decimal, Not Unary

Big O 2/14/13. Administrative. Does it terminate? David Kauchak cs302 Spring 2013

CMPS 6610 Fall 2018 Shortest Paths Carola Wenk

FINITE ABELIAN GROUPS Amin Witno

Fermat's Little Theorem

CS 161 Summer 2009 Homework #2 Sample Solutions

Recommended readings: Description of Quicksort in my notes, Ch7 of your CLRS text.

The L Machines are very high-level, in two senses:

Trees. A tree is a graph which is. (a) Connected and. (b) has no cycles (acyclic).

Discrete Math Notes. Contents. William Farmer. April 8, Overview 3

Dynamic Programming. Cormen et. al. IV 15

Measurement and Data Core Guide Grade 1

Section Summary. Sequences. Recurrence Relations. Summations Special Integer Sequences (optional)

Slides for CIS 675. Huffman Encoding, 1. Huffman Encoding, 2. Huffman Encoding, 3. Encoding 1. DPV Chapter 5, Part 2. Encoding 2

Central Algorithmic Techniques. Iterative Algorithms

directed weighted graphs as flow networks the Ford-Fulkerson algorithm termination and running time

Transcription:

Assignment 4 CSci 3110: Introduction to Algorithms Sample Solutions Question 1 Denote the points by p 1, p 2,..., p n, ordered by increasing x-coordinates. We start with a few observations about the structure of bitonic tours and paths, which will help us to derive a dynamic programming algorithm for computing a shortest bitonic tour. Observation 1 Points p n 1 and p n are neighbours in any bitonic tour that visits points p 1, p 2,..., p n. Proof. Assume that p n 1 is not a neighbour of p n. Then let p i and p j be the two neighbours of p n. The tour visits points p i, p j, p n 1, p n in the order p i, p n, p j, p n 1. However, both p i and p j have smaller x-coordinates than p n 1 and p n. Hence, the tour cannot be bitonic. Observation 1 implies that edge (p n 1, p n ) is present in any bitonic tour that visits all points. Hence, to find a shortest such tour, it suffices to concentrate on minimizing the length of the bitonic path from p n 1 to p n that is obtained by removing edge (p n 1, p n ) from the tour. We make the following observation about the structure of this path: Let p k be the neighbour of p n on this path. If we remove p n, we obtain a bitonic path P from p k to p n 1. If we remove p n 1 from P, we obtain a bitonic path that visits points p 1, p 2,..., p n 2 and has p n 2 as one of its endpoints. So let us concentrate on bitonic paths between any two points p i and p j, i < j, that visit all points p 1, p 2,..., p j. We call such a path a normal bitonic path. Observe that the path from p n 1 to p n that we want to compute is normal. Next we prove that shortest normal bitonic paths have an optimal substructure. Observation 2 Given a normal bitonic path P with endpoints p i and p j, i < j, let p k be the neighbour of p j on this path. Then the path P obtained by removing p j from P is a normal bitonic path with endpoints p i and p k. In particular, p j 1 {p i, p k }. If P is a shortest normal bitonic path with endpoints p i and p j, then P is a shortest normal bitonic path with endpoints p i and p k. Proof. Clearly, if we remove an endpoint from a bitonic path, the resulting path is still bitonic. Hence, P is a bitonic path with endpoints p i and p k. Moreover, it has to visit all points p 1, p 2,..., p j 1 because P visits all points p 1, p 2,..., p j, and p j is the only point we have removed from P to obtain P. Now assume that p j 1 {p i, p k }. Then P visits points p i, p k, p j 1, p j in the order p i, p j 1, p k, p j. Since p i and p k have x-coordinates less than those of p j 1 and p j, P cannot be bitonic, a contradiction. Now let us prove that P is shortest if P is shortest. Assume that there exists a shorter normal bitonic path P from p i to p k. Then we would obtain a shorter bitonic path P from

p i to p j by appending edge (p k, p j ) to P. Indeed, since x(p j ) > x(p k ), P is bitonic; it is normal, as it visits all points p 1, p 2,..., p j and has p j as an endpoint; and it is shorter than P because l(p ) = l(p ) + dist(p k, p j ) > l(p ) + dist(p k, p j ) = l(p ). From Observation 2, we obtain another simple observation that allows us to derive a formula for computing the length of a shortest normal bitonic path from p n 1 to p n. Observation 3 Consider the neighbour p k of p j in a normal bitonic path P with endpoints p i and p j, i < j. If i = j 1, we have 1 k < i. If i < j 1, we have k = j 1. Proof. In the first case, p k has to be a point in {p 1, p 2,..., p j } \ {p i, p j }. This leaves us with exactly the listed choices. In the second case, we obtain from Observation 2 that one of the endpoints of the subpath of P obtained by removing p j from P must be p j 1. Since p i p j 1, we have p k = p j 1. Making the observation that there exists only one normal bitonic path from p 1 to p 2, namely the one consisting of edge (p 1, p 2 ), we obtain the following formula for computing the length l(i, j) of a shortest normal bitonic path with endpoints p i and p j, i < j: dist(p i, p j ) if i = 1 and j = 2 l(i, j) = l(i, j 1) + dist(p j 1, p j ) if i < j 1. min 1 k<i (l(k, i) + dist(p k, p j )) if j > 2 and i = j 1 Before we present our algorithm to compute a shortest bitonic travelling-salesman tour, we make the following observations about the necessary information to construct such a tour, once we have computed all values l(i, j), 1 i < j n. We can obtain a shortest normal bitonic path from p i to p j by choosing the correct neighbour p k in such a path, recursively finding a shortest normal bitonic path from p i to p k, and finally appending edge (p k, p j ). How do we find this correct neighbour? If i < j 1, there is only one choice: p k = p j 1, by Observation 3. If i = j 1, p k is the point that minimizes the expression l(k, i) + dist(p k, p j ) because this is the value we have assigned to l(i, j). So, in order to construct a shortest bitonic travelling-salesman tour, we only have to record, for every pair (i, j), which is the neighbour p k of p j in a shortest normal bitonic path from p i to p j. We store this information in an array N; that is, N[i, j] stores the index k of this neighbour p k. One other observation is in order: We have to make sure that, whenever we compute a value l(i, j), the values l(i, j ) this computation relies on have already been computed. Now, according to our formula above, the computation of l(i, j) relies on values l(k, j 1). Hence, if we fill in the table column by column assuming that we use i to index the rows and j to index the columns everything is in order. What remains to be done is to list the algorithm:

Bitonic-TSP(p) 1 n p 2 Compute l(i, j) and N(i, j), for all 1 i < j < n. 3 for j = 2..n 4 do for i = 1..j 1 5 do if i = 1 and j = 2 6 then l[i, j] dist(p[i], p[j]) 7 N[i, j] i 8 else if j > i + 1 9 then l[i, j] l[i, j 1] + dist(p[j 1], p[j]) 10 N[i, j] j 1 11 else l[i, j] + 12 for k = 1..i 1 13 do q l[k, i] + dist(p[k], p[j]) 14 if q < l[i, j] 15 then l[i, j] q 16 N[i, j] k 17 Construct the tour. Stacks S[1] and S[2] will be used to construct the two x-monotone parts of the tour. 18 Let S be an array of two initially empty stacks S[1] and S[2]. 19 k 1 20 i = n 1 21 j = n 22 while j > 1 23 do Push(S[k], j) 24 j N[i, j] 25 if j < i 26 then swap i j 27 k 3 k 28 Push(S[1], 1) 29 while S[2] is not empty 30 do Push(S[1], Pop(S[2])) 31 for i = 1..n 32 do T [i] Pop(S[1]) 33 return T The final question to be answered concerns the running time of the algorithm. It is easy to see that Lines 17 33 take linear time. Indeed, the loop in Lines 31 32 is executed n times and performs constant work per iteration. The loop in Lines 29 30 is executed S[2] times, and each iteration takes constant time; hence, it suffices to prove that S[2] n after the execution of Lines 17 28. To prove this, it suffices to show that the loop in Lines 22 27 is executed at most n 1 times because every iteration pushes only one entry onto stack S[1]

or S[2]. The loop in Lines 22 27 takes constant time per iteration. It is executed until j = 1. However, initially j = n, and the computation performed inside the loop guarantees that j decreases by one in each iteration. Hence, the loop is executed at most n 1 times. To analyze the running time of Lines 1 16, we first observe that this part of the algorithm consists of two nested loops; the code in Lines 5 16 is executed Θ(n 2 ) times because i runs from 2 to n and in every iteration of the outer loop, j runs from 1 to i 1. Now, we perform constant work inside the loop unless i = j 1. In the latter case, we execute the loop in Lines 12 16 i 1 = O(n) times. Since there are only n 1 pairs (i, j) such that 1 i = j 1 < n 1, we spend linear time in only n 1 iterations of the two outer loops and constant time in all other iterations. Hence, the running time of Lines 1 16 is O(n 2 1 + n n) = O(n 2 ). Question 2 (20 marks) a. In order to use a greedy algorithm to solve this problem, we have to prove that the problem has optimal substructure and the greedy-choice property. The former is easy to prove: Let n be an amount for which we want to give change. Assume that optimal change for n cents includes a coin of denomination d. Then we obtain optimal change for n cents by giving optimal change for n d cents and then adding this d-cent coin. Indeed, if we could use less coins to give change for n d cents, we could also use less coins to give change for n cents by adding a d-cent coin to the set of coins we give as change for n d cents. The greedy-choice property is harder to prove. First, what is an obvious greedy choice to make? Well, if we want to give change for n cents, a greedy way to try to minimize the number of coins we use is to start with a coin of largest denomination d such that d n. We include this coin in the change and recursively give optimal change for n d cents. Let us prove that this works with denominations d 0 = 1, d 1 = 5, d 2 = 10, d 3 = 25. We prove by induction on i and n that optimal change using denominations d 0,..., d i always includes n/d i coins of denomination d i. This then immediately implies that optimal change does indeed always include at least one coin of the highest denomination d i n, which is the greedy choice property we want to prove. So consider the case i = 0. Then the only choice we have is to give n = n/d 0 pennies. If i = 1 and n < 5, we can only give pennies, which matches the claim that we give 0 = n/d 1 nickels. If n 5, there has to be at least one nickel. Otherwise, we could give better change by replacing 5 pennies with a nickel. By the optimal substructure property, we obtain optimal change for n cents by adding optimal change for n 5 cents to the nickel. By the induction hypothesis, optimal change for n 5 cents includes (n 5)/d 1 = n/d 1 1 nickels. Hence, the optimal change for n cents includes n/d 1 nickels. If i = 2 and n < 10, we can only give pennies and nickels, which matches the claim that we give 0 = n/d 2 dimes. If n 10, there has to be at least one dime. Otherwise,

the optimal change would have to include at least 2 nickels, which we could replace with a dime to get better change. By the optimal substructure property, we obtain optimal change for n cents by adding optimal change for n 10 cents to the dime. By the induction hypothesis, optimal change for n 10 cents includes (n 10)/d 2 = n/d 2 1 dimes. Hence, the optimal change for n cents includes n/d 2 dimes. If i = 3 and n < 25, we can only give pennies, nickels, and dimes, which matches the claim that we give 0 = n/d 3 quarters. If n 25, there has to be at least one quarter. Otherwise, there would have to be two dimes and a nickel if n < 30 or three dimes if n 30. In the former case, we could obtain better change by replacing the two dimes and the nickel with a quarter. In the latter case, we could replace the three dimes with a quarter and a nickel. By the optimal substructure property, we obtain optimal change for n cents by adding optimal change for n 25 cents to the quarter. By the induction hypothesis, optimal change for n 25 cents includes (n 25)/d 3 = n/d 3 1 quarters. Hence, the optimal change for n cents includes n/d 3 quarters. From this discussion, we conclude that the following algorithm gives optimal change. The arguments are: n: the amount we want to change k: the number of denominations 1 (since indexing starts at 0) d: an array of denominations sorted from the lowest to the highest The algorithm returns an array C of size k such that C[i], 0 i k, is the number of coins of denomination d[i] that have to be included in optimal change for n cents. Greedy-Change(n, k, d) 1 Initially, we have not given any change yet. 2 for i = 0..d 3 do C[i] 0 4 Now give change. 5 i k 6 while n > 0 7 do if n d[i] 8 then n n d[i] 9 C[i] C[i] + 1 10 else i i 1 11 return C The running time of the algorithm is O(k + n). To see this, observe that the for-loop in Lines 2 3 is executed k times; the while-loop in Lines 6 10 is executed until n = 0. However, in every iteration either i decreases by one or n decreases by d i 1. Hence, the while-loop is executed O(k + n) times. Since every iteration takes constant time, this establishes the claimed time bound.

b. To give optimal change using denominations d 0, d 1,..., d k such that d i = c i, for some integer c > 1, we use the algorithm from Question a. Our proof of the optimal substructure property in Question a does not rely on any particular properties of the coin denominations. Hence, it remains valid. What we have to verify is that, for denominations d 0, d 1,..., d k, the greedy strategy of choosing a largest denomination d i n and then giving optimal change for the amount n d i gives optimal change. Again, we prove by induction on i and n that optimal change for n cents using denominations d 0, d 1,..., d i includes n/d i coins of denomination d i. The base case (i = 0) is to give n = n/d 0 coins of denomination d 0 = 1. So assume that i > 0. If n < d i, then we can only use coins d 0, d 1,..., d i 1 to give change for n cents. Hence, our claim holds that we give 0 = n/d i coins of denomination d i. If n d i, we observe that optimal change has to include at least one coin of denomination d i. Otherwise, the induction hypothesis implies that optimal change includes n/d i 1 d i /d i 1 = c coins of denomination d i 1 ; c of them can be replaced with a single coin of denomination d i. Since optimal change contains at least one coin of denomination d i if n d i, we conclude from the optimal substructure property that we can obtain optimal change for n cents by adding this coin of denomination d i to optimal change for n d i cents. By the induction hypothesis, optimal change for n d i cents includes (n d i )/d i = n/d i 1 coins of denomination d i. Hence, optimal change for n cents includes n/d i coins of denomination d i, as claimed. c. Here s an example: d 0 = 1, d 1 = 7, and d 2 = 10. For 14 cents, our algorithm would produce 5 coins 10 + 1 + 1 + 1 + 1. Optimal change is 7 + 7. d. We have shown in the answer to Question a that the problem has optimal substructure. This proof was independent of the coin denominations. Hence, we can use a dynamic programming algorithm based on the following equation, where N(i) denotes the number of coins in an optimal solution for i cents: 0 if i = 0 N(i) = min{1 + N(i d j ) : 1 j k and d j i} if i > 0 The algorithm is the following:

Optimal-Change(n, k, d) 1 N[0] 0 2 for i = 1..n 3 do N[i] + 4 for j = k, k 1,..., 0 5 do if d[j] i 6 then q N[i d[j]] + 1 7 if q < N[i] 8 then N[i] q 9 G[i] is the largest coin denomination used in optimal change for i cents. 10 G[i] d[j] 11 for i = 0..k 12 do C[i] 0 13 while n > 0 14 do C[G[n]] C[G[n]] + 1 15 n n G[n] 16 return C The correctness of this algorithm follows from our above discussion. The running time is O(kn): To see this, we have to count how often every loop is executed because, inside each loop, we perform only constant work. The loop in Lines 2 10 is executed n time; the loop in Lines 4 10 is executed k + 1 times per iteration of the outer loop; hence, Lines 1 10 take O(kn) time. The loop in Lines 11 12 is executed k +1 times. The loop in Lines 13 15 is executed at most n times because it is executed until n = 0 and n decreases by at least one in every iteration of the loop. Hence, Lines 11 16 take O(n + k) time, and the total running time is indeed O(kn).