P. 1
Untitled

# Untitled

|Views: 96|Likes:

See more
See less

08/03/2012

pdf

text

original

# CMSC 451 Design and Analysis of Computer Algorithms1 David M.

Mount Department of Computer Science University of Maryland Fall 2003 1Copyright, David M. Mount, 2004, Dept. of Computer Science, University of Maryl and, College Park, MD, 20742. These lecture notes were prepared by David Mount for the course CMSC 451, Design and Analysis of Computer Algorithms, at the University of Maryland. Permission to use, copy, modify, and distribute these notes for educational purposes and witho ut fee is hereby granted, provided that this copyright notice appear in all copies. Lecture Notes 1 CMSC 451 Lecture 1: Course Introduction Read: (All readings are from Cormen, Leiserson, Rivest and Stein, Introduction t o Algorithms, 2nd Edition). Review Chapts. 1–5 in CLRS. What is an algorithm? Our text defines an algorithm to be any well-defined compu tational procedure that takes some values as input and produces some values as output. Like a cooking recipe, an al gorithm provides a step-by-step method for solving a computational problem. Unlike programs, algorithms are not dependent on a particular programming language, machine, system, or compiler. They are mathematical entiti es, which can be thought of as running on some sort of idealized computer with an infinite random access mem ory and an unlimited word size. Algorithm design is all about the mathematical theory behind the design of good programs. Why study algorithm design? Programming is a very complex task, and there are a number of aspects of programming that make it so complex. The first is that most programming projects are very la rge, requiring the coordinated efforts of many people. (This is the topic a course like software engineering.) The next is that many programming projects involve storing and accessing large quantities of data effi ciently. (This is the topic of courses on data structures and databases.) The last is that many programming pro jects involve solving complex computational problems, for which simplistic or naive solutions may not be effic ient enough. The complex problems may involve numerical data (the subject of courses on numerical analysi s), but often they involve discrete data. This is where the topic of algorithm design and analysis is impor tant. Although the algorithms discussed in this course will often represent only a tin y fraction of the code that is generated in a large software system, this small fraction may be very important for the success of the overall project. An unfortunately common approach to this problem is to first design an inefficient algorithm and data structure to solve the problem, and then take this poor design and attempt to fine-tune its performance. The problem is that if the underlying design is bad, then often no amount of fine-tu ning is going to make a substantial difference. The focus of this course is on how to design good algorithms, and how to analyze their efficiency. This is among the most basic aspects of good programming.

Course Overview: This course will consist of a number of major sections. The fir st will be a short review of some preliminary material, including asymptotics, summations, and recurrences and sor ting. These have been covered in earlier courses, and so we will breeze through them pretty quickly. We will t hen discuss approaches to designing optimization algorithms, including dynamic programming and greedy algo rithms. The next major focus will be on graph algorithms. This will include a review of breadth-first a nd depth-first search and their application in various problems related to connectivity in graphs. Next we will discuss minimum spanning trees, shortest paths, and network flows. We will briefly discuss algorithmic problems arising from geometric settings, that is, computational geometry. Most of the emphasis of the first portion of the course will be on problems that can be solved efficiently, in the latter portion we will discuss intractability and NP-hard problems. These are pr oblems for which no efficient solution is known. Finally, we will discuss methods to approximate NP-hard probl ems, and how to prove how close these approximations are to the optimal solutions. Issues in Algorithm Design: Algorithms are mathematical objects (in contrast to the must more concrete notion of a computer program implemented in some programming language and executing on som e machine). As such, we can reason about the properties of algorithms mathematically. When designing an algorithm there are two fundamental issues to be considered: correctness and efficiency. It is important to justify an algorithm’s correctness mathematically. For very com plex algorithms, this typically requires a careful mathematical proof, which may require the proof of many lemma s and properties of the solution, upon which the algorithm relies. For simple algorithms (BubbleSort, fo r example) a short intuitive explanation of the algorithm’s basic invariants is sufficient. (For example, in Bu bbleSort, the principal invariant is that on completion of the ith iteration, the last i elements are in their pro per sorted positions.) Lecture Notes 2 CMSC 451 Establishing efficiency is a much more complex endeavor. Intuitively, an algorit hm’s efficiency is a function of the amount of computational resources it requires, measured typically as exec ution time and the amount of space, or memory, that the algorithm uses. The amount of computational resources can be a complex function of the size and structure of the input set. In order to reduce matters to their sim plest form, it is common to consider efficiency as a function of input size. Among all inputs of the same size, we co nsider the maximum possible running time. This is called worst-case analysis. It is also possible, and often more meaningful, to measure average-case analysis. Average-case analyses tend to be more complex, and may re quire that some probability distribution be defined on the set of inputs. To keep matters simple, we will us ually focus on worst-case analysis in this course. Throughout out this course, when you are asked to present an algorithm, this mea ns that you need to do three things:

Present a clear, simple and unambiguous description of the algorithm (in pseudo -code, for example). They key here is “keep it simple.” Uninteresting details should be kept to a minimum, so that the key computational issues stand out. (For example, it is not necessary to declare variables whose p urpose is obvious, and it is often simpler and clearer to simply say, “Add X to the end of list L” than to present code to do this or use some arcane syntax, such as “L:insertAtEnd(X).”) Present a justification or proof of the algorithm’s correctness. Your justificati on should assume that the reader is someone of similar background as yourself, say another student in this class, and should be convincing enough make a skeptic believe that your algorithm does indeed solve the problem correctly. Avoid rambling about obvious or trivial elements. A good proof provides an overview of what the algorithm does, and then focuses on any tricky elements that may not be obvious. Present a worst-case analysis of the algorithms efficiency, typically it runnin g time (but also its space, if space is an issue). Sometimes this is straightforward, but if not, concentrate o n the parts of the analysis that are not obvious. Note that the presentation does not need to be in this order. Often it is good t o begin with an explanation of how you derived the algorithm, emphasizing particular elements of the design tha t establish its correctness and efficiency. Then, once this groundwork has been laid down, present the algorithm itself. If this seems to be a bit abstract now, don’t worry. We will see many examples of this process throughout th e semester. Lecture 2: Mathematical Background Read: Review Chapters 1–5 in CLRS. Algorithm Analysis: Today we will review some of the basic elements of algorithm analysis, which were covered in previous courses. These include asymptotics, summations, and recurrences. Asymptotics: Asymptotics involves O-notation (“big-Oh”) and its many relatives, , , o (“little-Oh”), !. Asymptotic notation provides us with a way to simplify the functions that arise in analyzin g algorithm running times by ignoring constant factors and concentrating on the trends for large values of n. For example, it allows us to reason that for three algorithms with the respective running times n3 log n + 4n2 + 52nlog n 2 (n3 log n) 15n2 + 7nlog3 n 2 (n2) 3n + 4 log5 n + 19n2 2 (n2): Thus, the first algorithm is significantly slower for large n, while the other t wo are comparable, up to a constant factor. Since asymptotics were covered in earlier courses, I will assume that this is fa miliar to you. Nonetheless, here are a few facts to remember about asymptotic notation: Lecture Notes 3 CMSC 451 Ignore constant factors: Multiplicative constant factors are ignored. For exampl e, 347n is (n). Constant factors appearing exponents cannot be ignored. For example, 23n is not O(2n). Focus on large n: Asymptotic analysis means that we consider trends for large va lues of n. Thus, the fastest growing function of n is the only one that needs to be considered. For example, 3n2 log n + 25nlog n +

there are no terms in the summation (since the index i s assumed to count upwards only). (The starting bound could have just as easily been set to 1 as 0. Xn .(log n)7 is (n2 log n). such as (log n)7. express this as nlog2 3 n1:585. the following formulas are useful. rather than saying 3log2 n. Exponential: A constant (not 1) raised to the power n. 0): Notice that when b = a − 1. sinc e an asymptotic approximation or close upper bound is usually good enough. if we let mean “asymptotically smaller” the n loga n nb cn for any a. and the result is 0. or other complex operators. Here a. provided that b > 0 and c > 1. Also. one having no summations. (This is just because it is easier to say “oh” than “theta”. such as recurrences. and c. Be careful to check that b a−1 before applying this formula blindly. For example.) Lecture Notes 4 CMSC 451 Geometric Series: Let x 6= 1 be any constant (independent of n). Xb i=a 1 = max(b − a + 1.) Summations: Summations naturally arise in the analysis of iterative algorithms. Arithmetic Series: For n 0. For example. more complex forms of analysis. Following the conventional sloppiness. when in fact the stronger statement (n2) holds. Here are some common summations and so me tips to use in solving summations. Polylog. such as 3n. I will often say O(n2). that is. and exponential: These are the most common functions that a rise in analyzing algorithms: Polylogarithmic: Powers of log n. which are strictly asymptotically smaller than exponential functions ( assuming the base of the exponent is bigger than 1). then for n 0. are often solved by reducing them to summations. Constant Series: For integers a and b. recurrences. Logarithm Simplification: It is a good idea to first simplify terms involving lo garithms. such as n4 and p n = n1=2. polynomial. We will usually write this a s log7 n. Xn i=0 i = 1+2+ +n = n(n + 1) 2 : This is (n2). b. b. Solving a summation means reducing it to a closed form formula. An important fact is that polylogarithmic functions are strictly asymptotically smaller than polynomial function. In algorithm design it is often not necessary to solve a summation exactly. Polynomial: Powers of n. The last rule above can be used to achieve this. For example. c are constants: logb n = loga n loga b = (loga n) loga(nc) = cloga n = (loga n) bloga n = nloga b: Avoid using log n in exponents. int egrals.

i=0 xi = 1+x+x2 + +xn = xn+1 − 1 x − 1 : If 0 < x < 1 then this is (1). then for n 0. nX−1 i=0 ixi = x + 2x2 + 3x3 +nxn = (n − 1)x(n+1) − nxn + x (x − 1)2 : As n becomes large. that is. but it can be closely approximated. and. we m ay multiply this times the constant (x − 1)2=x without changing the asymptotics. Hn = Xn i=1 1 i = 1+ 1 2 + 1 3 + + 1 n = (ln n) +O(1): There are also a few tips to learn about solving summations. Xn i=0 i2 = 12 + 22 + +n2 = 2n3 + 3n2 +n 6 : Linear-geometric Series: This arises in some algorithms based on trees and recur sion. . you can just split it up into the difference of two summations. a s most of the above formulas assume. the entire su m is proportional to the last element of the series. For exam ple. If x > 1. Let x 6= 1 be any constant. then this is (xn). The multiplicative term n − 1 is very nearly equal to n for large n. since x is a constant. Harmonic Series: This arises often in probabilistic analyses of algorithms. this is asymptotically dominated by the term (n − 1)x(n+1)=(x − 1)2. It d oes not have an exact closed form solution. for 1 a b Xb i=a f(i) = Xb i=0 f(i) − aX−1 i=0 f(i): Linearity of Summation: Constant factors and added terms can be split out to mak e summations simpler. What remains is (nx n). Summations with general bounds: When a summation does not start at the 1 or 0. For n 0. Quadratic Series: For n 0.

Chose your representation to make the algorithm as simple and clear as possible. 4. consider the following simple problem. we will first present a naive O(n2) time algorithm. In order to make this more concrete. think a little harder.) To illustrate summations. 3i The sequence of right dominant elements are h13. as is the last occurrence of the maximum element of th e array. 13. 6. (This is common in a lgorithms. Note that the last element of the list Lecture Notes 5 CMSC 451 is always right dominant. 7. Approximate using integrals: Integration and summation are closely related. 8. 5. consider the following list. For example. However. Z n 0 f(x)dx Xn i=1 f(i) Z n+1 1 f(x)dx: Example: Right Dominant Elements As an example of the use of summations in algor ithm analysis. 9. so it could also be implemented using a singly linked or doubly linked list. (Int egration is in some sense a continuous form of summation. Let f(x) be any monoto nically increasing function (the function increases as x increases).) We wil l assume here that the array L of size n is indexed from 1 to n. L = h10. We are given a list L of numeric values. 8. 3i. Remember that algorithms are read by humans. 1. . we will design the algorithm in such a way that it only performs sequen tial scans.X (4 + 3i(i − 2)) = X 4 + 3i2 −6i = X 4 + 3 X i2 −6 X i: Now the formulas can be to each summation individually.) Here is a handy formula. or a singly linked list (allowing for sequential acc ess in only one direction). which operates by simply checking for each element of the array whether all the subsequent elem ents are strictly smaller. Can you see an O(n) time al gorithm? (If not. It will make a difference whether L is represented as an array (allowing for random access). we should think about how L is represented. Among the three possible representations. Think for a moment how you would solve this problem. not compilers. We say that a n element of L is right dominant if it is strictly larger than all the elements that follow it in the li st. the array representation seems to yield the simplest and clearest algorithm. 6. a doubly link ed list (allowing for sequential access in both directions). 2. but give thought to how i t may actually be implemented.

. Again. up to a constant factor. as a function of n.) Recurrences: Another useful mathematical tool in algorithm analysis will be recu rrences. it will also serve to illustrate the so rt of style that we will use in presenting algorithms. for a total of n − (i + 1) + 1 = n−i times. the inner loop is executed from i + 1 to n. and put it into a form such that the above formulas can be used. this sort of optimizat ion is good to keep in mind in programming. (Recall the rule for the constant series above.(Although this example is pretty stupid. Conquer: Solve each subproblem recursively. I would rewrite the inner (j) loop as a while loop.n] // Returns: List D containing the right dominant elements of L RightDominant(L) { D = empty list for (i = 1 to n) isDominant = true for (j = i+1 to n) if (A[i] <= A[j]) isDominant = false if (isDominant) append A[i] to D } return D } If I were programming this. The time spent in this algorithm is dominated (no pun intended) by the time spen t in the inner (j) loop. is given by the f ollowing summation: T(n) = Xn i=1 (n − i): To solve this summation. let us expand it. the running time.) Each iteration of the in ner loop takes constant time. . since we can terminate the loop as soon as we find that A[i] is not dominant. see if you can find it. (You are allowed to use up to O(n) working storage to do this. Divide: Divide the problem into two or more subproblems (ideally of roughly equa l sizes). T(n) = (n−1) + (n − 2) + : : : + 2 + 1 + 0 = 0 + 1 + 2 + : : : + (n−2) + (n − 1) = nX−1 i=0 i = (n − 1)n 2 : Lecture Notes 6 CMSC 451 The last step comes from applying the formula for the linear series (using n − 1 i n place of n in the formula). They arise naturally in the analysis of divide-and-conquer algorithms. As a n exercise. there is a simple O(n) time algorithm for this problem. On the ith iteration of the outer loop. Recall that these algorithms have the following general structure. As mentioned above. but will be omitted since it will not affect the worst-case running time. see if you can design your algorithm so it only performs a single left-to-right scan of the list L. and Combine: Combine the solutions to the subproblems into a single global solution.) Right Dominant Elements (Naive Solution) // Input: List L of numbers given as an array L[1. Thus. As an additional challenge.

There are a number of methods for solving the sort of recurrences that show up i n divide-and-conquer algorithms. Lecture 3: Review of Sorting and Selection Read: Review Chapts. which assume that data is stored on disk or some other device that is best accessed sequentially. When the subproblems are reduced to size 1. this recurrence is not well def ined unless n is a power of 2 (since otherwise n=2 will at some point be a fraction). each associated with a given key value. but the Master Theorem (either this form or the one in CLRS will not tell you this. Theorem: (Simplified Master Theorem) Let a 1. which assume that data is stored in an array in main memory. Case 2: a = bk then T(n) is (nk log n). For example. Thus T(n) is (n log n). yielding the following recurren ce: T(n) = 1 if n = 1. Suppose that we break the problem in to two subproblems. other met hods are needed. This solves to T(n) = (nlog2 n). Sorting algorithms are usually divided into two classes. Here is a slig htly more restrictive version. since we assume that n is an integer. these algorithms are quite acce . I shoul d either write bn=2c or restrict the domain of n. There many recurrences that cannot be put into this form. then the best way is usually by setting up a recurrence. You are probably familiar with one or more of the standard simple (n2) sorting al gorithms. writing O(n) just as n. that is. given in CLRS. the follo wing recurrence is quite common: T(n) = 2T(n=2) + n log n. b = 2. See CLRS for the more complete ver sion of the Master Theorem and its proof. (By the way. b > 1 be constants and let T(n) be the recurrence T(n) = aT(n=b) + cnk. defined for n 0. and external sorting algorithm. The additional overhe ad of splitting and merging the solutions is O(n). such as InsertionSort. a funct ion which is defined recursively in terms of itself.). Case 1: a > bk then T(n) is (nlogb a). We will only consider inte rnal sorting. To be formally correct. SelectionSort and BubbleSort.How do we analyze recursive procedures like this one? If there is a simple patte rn to the sizes of the recursive calls. We will ignore constant factors. so a = bk and Case 2 applies. The easiest method is to apply the Master Theorem. We are given a sequence of items. The problem is to permute the items so t hat they are in increasing (or decreasing) order by key. Using this version of the Master Theorem we can see that in our recurrence a = 2 . internal sorting algori thms. Lecture Notes 7 CMSC 451 Review of Sorting: Sorting is among the most basic problems in algorithm design. Note that. Here is a typical example. Case 3: a < bk then T(n) is (nk). but I will often be sloppy in this way. T(n) = 2T(n=2) + n if n > 1. each of size roughly n=2. Sorting is important because it is often the first ste p in more complex algorithms. but adequate for a lot of instances. and k = 1. we can solve them in O(1) time. (We will assume exactly n=2 for simplicity.) For such recurrences. 6–9 in CLRS.

This is of interest. The three canonical efficient comparison-based sorting algorithms are MergeSort. All run in (n log n) time. since it uses no other array storage. It is nice to know that two items that are equal on the second key. depending on the application. remain sorted on the first key. but this is usually not counted. by first selecting a random “pivot value” from the array. It is a classical divide-and-conque r algorithm. Sorting algorithms often have additional properties that a re of interest. In-place: The algorithm uses no additional array storage. and HeapSort. They are sorted recursively. the probability that the algorithm takes asymptotically lo nger (assuming that the pivot is chosen randomly) is extremely small for large n. Here is a quick summary of the fast sorting algorithms. Lecture Notes 8 CMSC 451 MergeSort: MergeSort also works recursively. QuickSort. QuickSort: MergeSort: HeapSort: Heap extractMax x partition < x x > x sort sort x split sort merge buildHeap Fig. 1 QuickSort: It works recursively. This is considered an in-place sorting algorithm. and (n2) in the worst case. There is a stable version of QuickSort. (It does im plicitly use the system’s recursion stack. The other algorithms compare two elements in the arr ay.) BubbleSort is the easiest one to remember. Stable: A sorting algorithm is stable if two elements that are equal remain in t he same relative position after sorting is completed. Then the two sorted subarrays are . check out the descriptions in CLRS.ptable for small lists of. and hence (other than perhaps the system’s recursion stack) it is possible to sort very large lists without the need to allocate addi tional working storage. fewer than 20 elements. They are shown schematically in Fig. QuickSort is widely regarded as the fastest of the fast sorting algorithms (on m odern machines). which can be stored in a register for fast access. 1: Common O(n log n) comparison-based sorting algorithms.) It is not stable. but it widel y considered to be the worst of the three. Then it recur sively sorts each part. say. If properly implemented. Then it partitions the array into elements that are less than and greater than the pivot. One explanation is that its inner loop compares elements against a single pivot valu e. since in some sorting applications yo u sort first on one key and then on another. The array is split into two subarrays of roughly equal size. but it is not in-place. If you are not familiar with any of these. This algorithm is (n log n) in the expected case. Here are two important properties.

We will see that exceptions exist in special cases. This is because the merging process merges the two arrays into a t hird array. A comparison-based sorting algorithm is one in which algorithm permutes the elements based solely on the results of the comparisons that the al gorithm makes between pairs of elements. it is possible to select the kth smallest element in O(n) time. HeapSort: HeapSort is based on a nice data structure. since the fundam ental concepts covered there apply to much more complex algorithms. and the minimum key can be extracted in (log n) time. Lower Bounds for Comparison-Based Sorting: The fact that O(n log n) sorting algo rithms are the fastest around for many years. All of the algorithms we have discussed so far are comparison-based. related problem to sorting is selection. but this is the key to making this work as an in-place sorting algorithm. provided that the algorithm is comparison-based. where 1 k n. it cannot be done in (n) time. it is important to learn about sorting algorithms. and saves y ou from debugging time. Can we sort f aster? The claim is no. suggests that this may be the best that we can do. Which sorting algorithm should you implement when implementing your programs? Th e correct answer is probably “none of them”. which is an efficient implementation of a priority queue data structure.merged together in (n) time. a heap can allow you to do th is is (n+k log n) time. MergeSort is the only stable sorting algorithm of these three. The algorithm is a variant of Q uickSort. Unless you know that your input has some special properties that suggest a much faster alternative. Each change of priority (key value) can be processed in (log n) time. The downside is t he MergeSort is the only algorithm of the three that requires additional array storage (ignoring the recu rsion stack). Although selection can be solved in O(n log n) time. A priority queue supports the operations of inser ting a key. Although it is possible to merge arrays in-place. it has been engineered to produce the best performance for your system. but it is not stable. (Why it extract s the maximum rather than the minimum is an implementation detail. Nonetheless. and deleting the element with the smallest key value. called a heap.) If you only want to extract the k smallest values. it is best to rely on the library sorting procedure supplied on your system. return the kth smallest value of A. and an integer k. A heap can be built for n keys in (n) time. by first sorting A and then returning the kth element of the sorted list. and thus it is not in-place. A heap has the additional advantage of being used in contexts where the priority o f elements changes. HeapSort works by building the heap (ordered in reverse order so that the maximu m can be extracted efficiently) and then repeatedly extracting the largest element. HeapSort is an in-place sorting algorithm. Presumably. This does not preclude the possibility of sorting algorithms whos e actions are determined by . given an array A of n numbers (not sorted). The selection pro blem is. Selection: A simpler.

As the num ber of bits in each group increases. Linear Time Sorting: The (n log n) lower bound implies that if we hope to sort numbers faster than in O(n log n) time. but the space requirements go up. The algorithm requires an additional (n + k) working storage but has the ni ce feature that it is stable. Let’s think of our list as being composed of n integers. but deceptively clever. and then later we s .other operations. even if perfectly balanced. the algorithm is faster. we know that if the numbers are already sorted with respect to low order digits. Any sorting algorithm must be able to distinguish between each of the se different possibilities. called a decision tree. This can also be generalized to show that the average-case time to sort is also (n log n). must have at least n! leaves. This leads to the possibility of sorting in linear (that is. but quite tedious. Thus. Such a tree. The following theorem gives the lower b ound on comparison-based sorting. must height at least lg(n !). since two different permutations need to treated differently. (This i s a bit abstract. In some special cases. Plugging this in and simplifying yie lds the (n log n) lower bound. we cannot do it by making comparisons alone. By Stirling’s approximation. If the integers are in the range from say. The algorithm is remarkably simple. Here are three such algorithms. it is possible to sort without the use of comparisons. or generally. Theorem: Any comparison-based sorting algorithm has worst-case running time (n log n). The idea is very simple. You are refe rred to CLRS for the details. starting at the lowest order digit. some groups of bits. Counting Sort: Counting sort assumes that each input is an integer in the range from 1 to k. Radix Sort: The main shortcoming of CountingSort is that (due to space requireme nts) it is only practical for a very small ranges of integers. 1 to a million. if k is O(n). and finishing with the highest order digit. this implies that the resulting sortin g algorithm runs in (n) time. as we shall see below. n! Lecture Notes 9 CMSC 451 is. There are n! w ays to permute a given set of n numbers. Since each compari son leads to only two possible outcomes. roughly (n=e)n. up to constant factors. each having d decimal digits (or digits in any base).) This binary tree. the execution of the algorithm can be viewed as a binary tree. at a time. but the basic argument follows from a simple analysis of the number of possibilities and the time it takes to distinguish among them. We will not present a proof of this theorem. The algorithm sorts in (n + k) time. O(n)) time. but given a sorting algorithm it is not hard. Since the sorting algorithm i s stable. To sort these integers we simply sort repeatedly . o ne for each of the possible input permutations. to trace its execution. we may not want to allocate an array of a million elements. RadixSort provides a nice way around this by sorting numbers one digit. and set up a new node each time a decision is made. or one byte.

0:02). What if you want to sort a se t of floating-point numbers? In the worst-case you are pretty much stuck with using one of the comparison-bas ed sorting algorithms. [0:02. A common application of this algorithm is for sorting integers over some range t hat is larger than n. so even a quadrat ic time sorting . and k is the number of distinct values each digit may have. However.ort with respect to high order digits. the su bintervals would be [0. and using the floor function. In general this works to sort any n numbers over the ran ge from 1 to nd. (It is possible in O(n) time to find the maximum and minimum values. MergeSort. Then we make a pass through the list to be sorted.) Suppose that the numbers to be sorted range over some interval. or at least objects (like characters) that can be encoded as small integers. if n = 100. The running time is (d(n + k)) where d is the number of digits in each value. suppose that you wanted to sort a list of in tegers in the range from 1 to n2. The space needed is ( n + k). where each digit is ove r the range from 0 to n − 1. We create n different buckets. in special cases where you h ave reason to believe that your numbers are roughly uniformly distributed over some range. (Note Lecture Notes 10 CMSC 451 that this is a strong assumption. in (dn) time. given any integer L in this range. you could subtract 1 so that they are now in the range from 0 to n 2 − 1. the index of element x would be b100xc. For example.) We then so rt each bucket in ascending order. and scale the numbers to fit into this r ange. one for each interval. 2: Example of RadixSort. An example is shown in Figure 2. The number of points per bucket should be fairly small. numbers having the same high order digit will remain sorted with r espect to their low order digit. For example. 1). we can rad ix sort these numbers in time (2(n + n)) = (n). Input Output 576 49[4] 9[5]4 [1]76 176 494 19[4] 5[7]6 [1]94 194 194 95[4] 1[7]6 [2]78 278 296 =) 57[6] =) 2[7]8 =) [2]96 =) 296 278 29[6] 4[9]4 [4]94 494 176 17[6] 1[9]4 [5]76 576 954 27[8] 2[9]6 [9]54 954 Fig. Observe that any number in this range can be expressed as 2-digit number. 0:03). 0:01). we can write L = an + b. [0:01. but still polynomial in n. (In this case. This algorithm should not be applied unless yo u have good reason to believe that this is the case. So. First.) The idea is the subdivide this interval into n subintervals. BucketSort: CountingSort and RadixSort are only good for sorting small integers. then it is possible to do better. n i s the length of the list. or HeapSort. In particular. say [0. b). we can think of L as the 2-digit number (a. we c an map each value to its bucket index. Now. such as QuickSort. and so on. where a = bL=nc and b = L mod n.

3.81 . (Our text also discusses a top-down alternative.86 .56 9 4 B 0 1 2 3 5 6 7 8 . The technique is related to divide-and-conquer. Since there are n buckets. and Section 15.71 . (This is true for two reasons.71 .38 .17 . The analysis relies on the fact that. subject to various constraints). Dynamic Programming: We begin discussion of an important algorithm design techni que. called memoization.42 .59 . called dynamic programming (or DP for short).algorithm (e.14 . Finally. Table-structure: Store the answers to the subproblems in a table.10 . 3: BucketSort.59 .g.17 A Fig. in the sense that it breaks problems down into smaller problems that it solves recursively. assuming that the numbers are uniformly di stributed. BubbleSort or InsertionSort) should work.4 in CLRS. However. .86 .81 .10 . This is done b ecause subproblem solutions are reused many times. the number of elements lying within each bucket on average is a constant.38 . standard divide-and-conquer solutions ar e not usually efficient. the total sorting time is (n). The basic elements that characterize a dynamic programming algorithm are: Substructure: Decompose your problem into smaller (and hopefully simpler) subpro blems. . because of the somewhat different nature of dynamic programming problems. Lecture 4: Dynamic Programming: Longest Common Subsequence Read: Introduction to Chapt 15. the expected t ime needed to sort each bucket is O(1). Dynamic programming solutions are based on a few common elements. Bottom-up computation: Combine solutions on smaller subproblems to solve larger subproblems.) Lecture Notes 11 CMSC 451 The most important question in designing a DP solution to a problem is how to se t up the subproblem structure. Express the solution of the original problem in terms of solutions for smaller problems. Thus. The technique is among the most powerful for designing algori thms for optimization problems. all the sorte d buckets are concatenated together.14 . An exam ple illustrating this idea is given in Fig. Dynamic programming problems are typically optimization problems (find the minim um or maximum cost solution.42 .56 .

DP Formulation for LCS: The simple brute-force solution to the problem would be to try all possible subsequences from one string. One common method of measuring the degree of similarity between two strings is to compute their lo ngest common subsequence. : : : . : : : . let X = hABRACADABRAi and let Y = hYA BBADABBADOOi. the longest common subsequence of X and Y is a longe st sequence Z that is a subsequence of both X and Y . : : : .This is called the formulation of the problem. : : : . In typical DP fashion. Xik i. zki.Xi2. There are a number of important problems here. w e need to break the problem into smaller pieces. (Not all optimi zation problems satisfy this. i2. 4 Y A B B A D A B A D O O X = Y = B A LCS = A B A D A B A B R A C A D A B R A Fig. Instead.) It states that for the global problem to be solved optimally. yni determine a longest common subsequence. : : : . : : : . let X = hABRACADABRAi and let Z = hAADAAi. but rather something that is similar. xmi and Z = hz1. xmi and Y = hy1. z2. each subproblem should be solved optimally. but it turns ou t for this problem that . iki (1 i1 < i2 < : : : < ik n) such that Z = hXi1. There are two important elements that a problem must have in order for DP to be applicable. The Longest Common Subsequence Problem (LCS) is the following. Strings: One important area of algorithm design is the study of algorithms for c haracter strings. Then the longest common subsequence is Z = hABADABAi. and search for matches in the other string. See Fig. Given two sequences X = hx1. since there are an exponential number of possible subsequences. we will derive a dynamic programming solution. Dynamic programming is not applic able to all optimization problems. For example. but this is hopeles sly inefficient. we say that Z is a subseq uence of X if there is a strictly increasing sequence of k indices hi1. Longest Common Subsequence: Let us think of character strings as sequences of ch aracters. Optimal substructure: (Sometimes called the principle of optimality. For example the LCS of hABCi and hBACi is either hACi or hBCi. then Z is a subsequence of X. Note that it is not always unique. This arises for example in genetics research and in document retrieval on the web. 4: An example of the LCS of two strings X and Y . Sometimes it is better to lose a little on one subproblem in order to make a big gain on another. Among the most important has to do with efficiently searching for a substring or generally a pattern in large piece of text. Given two strings X and Y .) In many instances you do not want to find a piece of text exa ctly. There are many ways to do this for strings. Given two sequenc es X = hx1. For example.) Polynomially many subproblems: An important aspect to the efficiency of DP is th at the total number of subproblems to be solved should be at most a polynomial number. (This is what text editors and pr ograms like “grep” do when you perform a search. x2.

6] = 3. xii. Eventually we are interested in c[m. 5. (We will leave the proo f as an exercise. we compute all of them. j] values do we compute? Since we don’t know which will lead to the final optimum. Since both end in A. x2. For example: Let Xi = hABCAi and let Yj = hDACAi. n] since this will be the LCS of the two entire strings. j0]. in the above case we have X5 = hABRACi and Y6 = hYABBADi. If either sequence is empty. : : : . A prefix of a sequence is just an initial string of values. The idea is to compute c[i. Which of the c[i. 0] = c[j. X0 is the empty sequence. we claim that the LCS must also end in A. The idea will be to compute the longest common subsequence for every possible pa ir of prefixes. Here are the possible cases. giv ing hACAi as the answer. Lecture Notes 12 CMSC 451 Basis: c[i.) Since the A is part of the LCS we may find the overall LCS by removing A from both seq uences and taking the LCS of Xi−1 = hABCi and Yj−1 = hDACi which is hACi and then adding A to the end. then the longest comm on subsequence is empty. Let c[i. (At first you might object: But how did you know that these two A’s matched with each other. The answer is that we don’t. Thus. For example. Xi = hx1. j −1] + 1 LCS Y X A yj A A j j Y Xi A i−1 Last chars match: add to LCS j−1 i−1 j−1 x B LCS X LCS A Y max skip yj skip xi A B xi match Last chars do not .) This is illustrated at the top of Fig. Last characters match: Suppose xi = yj . Their longest common subsequence is hABAi. c[5. for i0 i and j0 j (but not both equal). but it will not make the LCS any smaller if we do.considering all pairs of prefixes will suffice for us. j] assuming that we already know the values of c[i0. 0] = 0. if xi = yj then c[i. j] = c[i−1. j] denote the length of the longest common subsequence of Xi and Yj .

if xi 6= yj then c[i. 5: The possibe cases in the DP formulation of LCS. j > 0 and xi = yj . c[i−1. The code is shown belo w. j]) if i. j] = max(c[i − 1. In the first case (xi is not in the LCS) the LCS of Xi and Yj is the LCS of Xi−1 a nd Yj . 5. which is c[i−1. our approach is to take advantage of the fact that we have already precomputed smaller subproblems. j > 0 and xi 6= yj . How ever. j −1] + 1 if i. By analyzing the l ast few characters of Xi and Yj . and use these results to guide us. At this point it may be tempting to try to make a “smart” choice. In the second case (yj is not in the LCS) the LCS is the LCS of Xi and Yj−1 which is c[i. Later we will see how to extract the ac tual sequence. j]. Implementing the Formulation: The task now is to simply implement this formulati on. j]. since it is a common point of confusion. 6 Lecture Notes 13 CMSC 451 LCS Length Table with back pointers included 2 2 3 =n 2 1 1 2 2 1 1 2 2 1 1 1 1 B D C B A B D C B . We do not know which is the case. j − 1]. so we try both and take the one that gives us the lo nger LCS. j] = 8< : 0 if i = 0 or j = 0. j − 1]) Combining these observations we have the following formulation: c[i. c[i−1. c[i. this approach is doomed to failure (and you are strongly encouraged to think about this. and an example is illustrated in Fig.y i B A Yj Xi Yj Xi Fig.) Instead. Thus either xi is not part of the LCS. We will store some helpful pointers in a parallel array. 0::n]. j − 1]. In this case xi and yj can not both be in the LCS (since they would have to be the last character of the LCS). or yj is not part of the LCS (and possibly both are not part of the LCS). This is illustrated at the bottom half of Fig. We concentrate only on computing the maximum length of the LCS. max(c[i. Last characters do not match: Suppose that xi 6= yj . perhaps we can figure out which character is best to discard. b[0::m.

. 0.m. y[1..4 3 2 1 0 0 2 3 4 m= 5 0 B 4 3 2 1 0 0 1 2 3 4 m= 5 =n start here X = BACDB X: X: Y: Y: D 1 1 1 1 1 0 0 0 0 0 0 0 0 0 B D C B A C B 0 1 1 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 2 Y = BDCB 1 2 2 3 LCS = BCB 1 2 2 2 2 Fig.m].j] = 0. b[0. j] and the arrow entries are used in the ex traction of the sequence.0] = 0. Build LCS Table LCS(x[1.0] = SKIPX for j = 0 to n // init row 0 c[0.n]) { // compute LCS table int c[0. 6: Longest common subsequence example for the sequences X = hBACDBi and Y = hBCDBi. b[i..j] = SKIPY for i = 1 to m // fill rest of table .n] for i = 0 to m // init column 0 c[i.. The numeric table entries are the values of c[i.

. break // skip X[i] case skipY: j--.j] = skipX else // Y[j] not in LCS c[i.j] >= c[i. Similarly. and continue with entry b[i − 1.n].j] = addXY else if (c[i-1. b[i. b[i.. j] above us ( "). j] = skipY . Lecture 5: Dynamic Programming: Chain Matrix Multiplication Read: Chapter 15 of CLRS. y[1. respectively. This me ans that we are free to parenthesize the above multiplication however we like. Intuitively b[i. j = n // start at lower right while(i != 0 && j != 0) // go until upper left switch b[i.j-1]. b[i. and outputting a character with each diagonal move gives the fina l subsequence.j] = c[i-1.0.j] = c[i. Suppose that we wish to multiply a series of matrices A1A2 : : : An Matrix multiplication is an associative but not a commutative operation. .j] = c[i-1. A pq matrix has p rows and q columns.j] case addXY: // add X[i] (=Y[j]) add x[i] (or equivalently y[j]) to front of LCSstring i--. there are restri ctions on the dimensions. and so we skip it and go to b[i. and Section 15.n]) { LCSstring = empty string i = m. j--. Chain Matrix Multiplication: This problem involves the question of determining t he optimal sequence for performing a series of operations. then we know that Y [j] is not in the LCS. b[0.j]. 0::n]. Following these back pointers. j] = skipX. but we are not free to rearrange the o rder of the matrices. and the result will be a p r matrix C.j-1]) // X[i] not in LCS c[i.j] = skipY return c[m. then we know that X[i] is not in the LCS. The algorithm also uses O(mn) space.for j = 1 to n if (x[i] == y[j]) // take X[i] (Y[j]) for LCS c[i. and so we skip it and go to b[i−1. if b[i.. break // skip Y[j] return LCSstring } Lecture Notes 14 CMSC 451 The running time of the algorithm is clearly O(mn) since there are two nested lo ops with m and n iterations. (The number of columns of A must equal the number of row s of B. j −1] to the left ( ).n] // return length of LCS } Extracting the LCS getLCS(x[1. We will study the problem in a very res tricted instance. So we take this common character. This general class of problem is important in compiler d esign for code optimization and in databases for query optimization. Extracting the Actual Sequence: Extracting the final LCS is done by using the ba ck pointers stored in b[0::m. If b[i. where the dynamic programming issues are easiest to see.2 in particular.. j] = addXY means that X[i] and Y [j] together form the last cha racter of the LCS. You can multiply a p q matrix A times a q r mat rix B.m]. Also recall that when two (nonsquare) matrices are being multiplied.m. break case skipX: i--. j −1] to the northwest (-).) In particular for 1 i p and 1 j r.j-1]+1.

Consider the case of 3 matrices: A1 be 5 4. Important Note: This algorithm does not perform the multiplications. then there are n − 1 places where yo u could break the list with the outermost pair of parentheses. namely just after the 1st item. etc. determine the order of multiplication (represent ed. considerable savings can be achieved by reordering the evaluation sequence. just after th e 2nd item. multCost[(A1(A2A3))] = (462) + (5 4 2) = 88: Even for this small example. : : : .C[i. as a binary tree) that minimizes the number of operations. Lecture Notes 15 CMSC 451 Chain Matrix Multiplication Problem: Given a sequence of matricesA1. j] entry of C is the dot product of the ith (horizontal) row of A and the jth (vertical) column of B. then the total is L R. n−1 . if there are L ways to parenthesize the left sublist an d R ways to parenthesize the right sublist. Naive Algorithm: We could write a procedure which tries all possible parenthesiz ations. the number of different ways of parenthesizing n items: P(n) = 1P if n = 1.A2. and just after the (n − 1)st item. say. An and dimensions p0. we create two sublists to b e parenthesized. Note that although any legal parenthesization will lead to a valid result. not a ll involve the same number of operations. This suggests the following recurrence for P(n).. A2 be 4 6 and A3 be 6 2. k]B[k. Since these are independent choices. j] = Xq k=1 A[i. pn where Ai is of dimension pi−1 pi. Then we could consider all the ways of parent hesizing these. the number of ways of parenthesizing an expression is very large. and the other with n−k items. one with k items. it just det ermines the best order in which to perform the multiplications. 7: Matrix Multiplication. j]: This corresponds to the (hopefully familiar) rule that the [i. If you have n items. then there is only one way to parenthesize. If you have just one or t wo matrices. B C = A p q q r r Multiplication time = pqr * = p Fig. thus the total time to multiply these two matrices is proportional t o the product of the dimensions. : : : . Unfortunately. p1. pqr. When we split just after the kth item. Observe that there are pr total ent ries in C and each takes O(q) time to compute. multCost[((A1A2)A3)] = (5 4 6) + (5 6 2) = 180.

1 k n − 1. In summary. Since matrices cannot be reordered. As is common to any DP solution. Since 4n is exponential and n3=2 is just polynomial. We want to break the problem int o subproblems. you may be tempted to consider some clever ideas. In particular P(n) = C(n−1). a parenthesization). (Think about this for a second to be sure you see why. where C (n) is the nth Catalan number: C(n) = 1 n + 1 2n n : Applying Stirling’s formula (which is given in our text). as is true in almost all dynamic programming solutions. this will not be practical except for very small n. we need to find some way to break the problem into smaller subproblems. A1::n = A1::k Ak+1::n: Thus the problem of determining the optimal sequence of multiplications is broke n up into two questions: how do we decide where to split the chain (what is k?) and how do we parenthesize th e subchains A1::k and Ak+1::n? The subchain problems can be solved recursively. and we need to determine a recursive formulation. the exponential will dominate. implying that functi on grows very fast.) Instead. So. It just turns out that it doesn’t in this case. This takes a bit of thinking. which represents the optimum solution to each problem in terms of solutions to the subproblems. let us think about the problem of determining the best value of k. Let Ai::j denote the result of multiplying matrices i through j. like other dynamic programming probl ems involves determining a structure (in this case. For example. in order to determine how to perform this multiplication optimally. since i t quickly leads to an exponential . whose solutions can be combined to solve the global problem. At this p oint. it makes sense to think about sequences of m atrices. This is related to a famous function in combinatorics called the Catalan numbers (which in turn is related to the number of different binary trees on n nodes). That is. (After all it might work. Although this is not a bad idea. In parenthesizing the expression. Usually trying all possible choices is bad. brute force is n ot an option. and taking the best of them. What we want to do is to break the problem into pro blems of a similar structure. It is easy to see that Ai::j is a pi−1 pj matrix. pick the value of k that minimizes pk. At this level we are simply multiplying two matrices together. which you should try.) Now. by applying the same scheme. in principle. Dynamic Programming Approach: This problem. we can consider the highest level of parenthes ization. since we want matrices with small dimen sions.k=1 P(k)P(n − k) if n 2. for any k. we find that C(n) 2 (4n=n3=2). we will do the dumbest thing of simply considerin g all possible choices of k. L et us think of how we can do this. Thus. we need to make many decisions.

..k i. For 1 i j n. by definition.. (There is nothing to multiply. let m[i. j] = min ik<j (m[i. This suggests the following recursive rule for computing m[i. Since Ai::k is a pi−1 pk matrix. Fig. k] and m[k+1. j]. (There are n 2 = n(n − 1)=2 ways of choosing i and j to form Ai::j to be precise. j] we nee d to access values m[i. Dynamic Programming Formulation: We will store the solutions to the subproblems in a table. j] + pi−1pkpj) for i < j. i]) are trivial to compute. We may assume that these values have been computed previously and are already st ored in our array. .. and build the table in a bottom-up manner. Basis: Observe that if i = j then the sequence contains only one matrix. Then we build up by comp uting the subchains of lengths . m[i. The only tricky part is arranging the order in which to compute the values. i] = 0.) Thus. m[i. we should compute each subs equence optimally.. i] = 0 m[i. because once we decide to break the sequence into the product A1::k Ak+1::n. The subchains of length 1 (m[i.) Thus. j] for k lying between i and j. the time to multiply the m is pi−1pkpj . 8: Dynamic Programming Formulation. k] +m[k + 1. as Ai::k times Ak+1::j .j A ? . m[i. and Ak+1::j is a pk pj matrix. and so the cost is 0. k] and m [k + 1. j] denote the minimum number of mul tiplications needed to compute Ai::j . That is. the subproblems must be solved op timally as well. Step: If i < j. then we are asking about the product Ai::j . j]. The optimum times to compute Ai::k and Ak+1::j are.. Let L = j−i+1 denote the length of the subc hain being multiplied. In the process of computing m[i. which is given below. for the global problem to be solved optimally.Lecture Notes 16 CMSC 451 number of total possibilities. This can be split b y considering each k. i k < j. It is not hard to convert this rule into a procedure. This suggests that we should organize our computation according to the number of matrices in the subsequence. What saves us here is that there are only O(n2) d ifferent sequences of matrices. i i+1 k k+1 j k+1. Notice that our chain matrix multiplication problem satisfies the principle of o ptimality. The optimum cost can be described by the following recursive formulation.. respectively. we do no t encounter the exponential growth.j A A A A A A A i.

1.n-1. j].n]) { array s[1. j] tells us what multiplication to perform last. and that s[i.2. j] = k.. : : : . j] in which we will stor e the value of k providing the optimal split. The running time of the procedure is (n3).2. We’ll leave this as an exercise in solving sums. i n−L+1.n] for i = 1 to n do m[i. that is. For example. } } } } return m[1. n. We need to be a little careful in setting up the loops. this means t hat i + L − 1 n.A[k] Y = Mult(k+1. if j > i.. s[i. // multiply matrices X and Y } . s[i. } value of m[i. j] when we have at least two matrices. The array s[i. j] + p[i-1]*p[k]*p[j] if (q < m[i.. or in other words. This tells us that the bes t way to multiply the subchain Ai::j is to first multiply the subchain Ai::k and then multiply the subchain Ak+ 1::j . suppose that s[i.j] = q. j] value to determine how to s plit the current sequence. then j = i + L − 1. The recursive procedure Mult does this computation and below returns a matrix. k] + m[k+1.A[j] return X*Y. The final answer is m[1.. j) // Y = A[k+1].j] X = Mult(i.. So our loop for i runs from 1 to n−L+1 (in order to keep j in bounds). Extracting the final Sequence: Extracting the actual multiplication sequence is a fairly easy extension. Since we want j n. the value of k that leads to the minimum Lecture Notes 17 CMSC 451 Chain Matrix Multiplication Matrix-Chain(array p[1. for k = i to j-1 do { // check all splits q = m[i. It is used to extract the actual sequ ence. but the key is that there are three nested loops. else { k = s[i. k) // X = A[i]. The code is presented below. Extracting Optimum Sequence Mult(i.i] = 0. If a subchain of length L starts at position i. m[i.j] = k. 3. Assume that the matrices are stored in an array of matrices A[1::n]. that is.j] = INFINITY. j] will be explained later.. Not e that we only need to store s[i. // initialize for L = 2 to n do { // L = length of subchain for i = 1 to n-L+1 do { j = i + L . and finally multiply these together. and each can iterate at most n times. n]. Intuitively.n] (final cost) and s (splitting markers). j] i s global to this recursive procedure. j) { if (i == j) // basis case return A[i]. We can maintain a parallel array s[i. j]) { m[i. The basic idea is to leave a split marker indicating what the best split is. The actual multiplication algorithm uses the s[i..

but actually has remarkable similarities. This algorithm is tricky. 4.j] 2 3 1 3 3 j 2 3 4 2 3 0 p 4 p 3 p Final order A1 A2 A3 A4 A1 A2 A3 A4 3 2 1 1 m[i. The optim al sequence is ((A1(A2A3))A4). 2. 9: Chain Matrix Multiplication Example. so it would be a good idea to trace through this example (and the one given in the text). Define a polygon to be a piecewise linear closed curve in the plane. we form a cycle by joining line segments end to end. Polygons and Triangulations: Let’s consider a geometric problem that outwardly app ears to be quite different from chain-matrix multiplication. We begin with a number of definitions. In other wo rds.} In the figure below we show an example. The line segments are called the sides of the polygon . Lecture Notes 18 CMSC 451 i 1 s[i. 6. 7i meaning that we are multiplying A1 (5 4) times A2 (4 6) times A3 (6 2) times A4 (2 7). Lecture 6: Dynamic Programming: Minimum Weight Triangulation Read: This is not covered in CLRS. The initial set of dimensions are h5.j] 1 2 3 4 1 2 3 4 4 p1 p2 5 158 88 120 48 104 84 0 0 0 0 j i 6 2 7 Fig.

) It is easy to see that such a set of chords subdivides the interior of the polygon into a collection of triangles with pairwise disjoint interiors (and hence the name tri angulation). (If the polygon is simple but not convex. A simple polygon is said to be convex if every interi or angle is at most 180 degrees. the number is exponential in n. vj+1. vji. the line segment vivj is a c hord. (This may sound fanciful. vi+1. 10: Polygons. : : : . In f act. . : : : . vk. A triangulation of a convex polygon P is a subdivision of the interior of P into a collection of triangles with disjoint interiors. (In other words. every chord that is not in T intersects the interior of some chord in T. vk) = jvivjj+jvjvkj+jvkvij. vj. 11: Triangulations of convex polygons. its boundary and its exterior. Polygon Simple polygon Convex polygon Fig. Given two nonadjacent sides vi and vj . bu t minimizing wire length is an Lecture Notes 19 CMSC 451 important condition in chip design. One criterion is to imagine that you must “pay” for the ink you use in drawing the triangulation. This poly gon has n sides. Given a convex polygon. (See Fig. In general. if the sides do not intersect one another except for two consecutive sides sharing a common vertex. vii. vi−1vi. It is not hard to prove (by induction) that every triangulation of an n-sided polygon consists of n − 3 ch ords and n − 2 triangles. whose vertices are drawn from the vertices of P. and you want to minimize the amount of ink you use. we include the additional requirement that the interior of the s egment must lie entirely in the interior of P. A polygon is simple if it does not cross itself. Dynamic Programming Solution: Let us consider an (n + 1)-sided polygon P = hv0. and the minimum weight triangulation . vj .) This suggests the following optimization problem: Minimum-weight convex polygon triangulation: Given a convex polygon determine th e triangulation that minimizes the sum of the perimeters of its triangles. there are many possible triangulations. Given three distinct vertices vi. Many geometric algorithm operate by first decomposing a complex polygonal shape into triangles.) Any chord subdivides the polygon into two polygons: hvi. this is one of many properties whic h we could choose to optimize. Which triangulation is the “best”? There are many criteria t hat are used depending on the application. so v0 = vn. Equivalentl y. We will assume that indexing of vertices is done modulo n. wherei < j−1. A simple polygon subdivides t he plane into its interior. Further. given a convex polygon. we can define a triangulation as a maximal set T of nonintersecting chords.) A triangulation Lower weight triangulation Fig. the number of sides. and hvj. we assume that its vertices are labeled in counterclockw ise order P = hv1. vni. we define the weight of the associate d triangle by the weight function w(vi. but for this problem we will assume that no such vertices exist. Triangulations are of interest for a number of reasons. 11. where jvivj j denotes the length of the line segment vivj .and the endpoints are called the vertices. : : : . that is. Vertices with interior angle equal to 180 degrees are normally allowed.

v1; : : : ; vni. Let us assume that these vertices have been numbered in counterclockwise order. To derive a DP formulation we need to define a set of subproblems from which we can derive the optimum solution. For 0 i < j n, define t[i; j] to be the weight of the minimum weight triangulation for the subpolygon that lies to the r ight of directed chord vivj , that is, the polygon with the counterclockwise vertex sequence hvi; vi+1; : : : ; vji . Observe that if we can compute this quantity for all such i and j, then the weight of the minimum weight triang ulation of the entire polygon can be extracted as t[0; n]. (As usual, we only compute the minimum weight. But, it is easy to modify the procedure to extract the actual triangulation.) As a basis case, we define the weight of the trivial “2-sided polygon” to be zero, i mplying that t[i; i+1] = 0. In general, to compute t[i; j], consider the subpolygon hvi; vi+1; : : : ; vji, where j > i+1. One of the chords of this polygon is the side vivj . We may split this subpolygon by introducing a tr iangle whose base is this chord, and whose third vertex is any vertex vk, where i < k < j. This subdivides the po lygon into the subpolygons hvi; vi+1; : : : vki and hvk; vk+1; : : : vji whose minimum weights are already known to us as t[i; k] and t[k; j]. In addition we should consider the weight of the newly added triangle 4vivkvj . Thus, we have the following recursive rule: t[i; j] = 0 if j = i + 1 mini<k<j(t[i; k] + t[k; j] +w(vivkvj)) if j > i + 1. The final output is the overall minimum weight, which is, t[0; n]. This is illus trated in Fig. 12 Note that this has almost exactly the same structure as the recursive definition used in the chain matrix multiplication algorithm (except that some indices are different by 1.) The same (n3) algorithm can be applied with only minor changes. Relationship to Binary Trees: One explanation behind the similarity of triangula tions and the chain matrix multiplication algorithm is to observe that both are fundamentally related to binary trees. In the case of the chain matrix multiplication, the associated binary tree is the evaluation tree for the multip lication, where the leaves of the tree correspond to the matrices, and each node of the tree is associated with a product of a sequence of two or more matrices. To see that there is a similar correspondence here, consider an ( n + 1)-sided convex polygon P = hv0; v1; : : : ; vni, and fix one side of the polygon (say v0vn). Now consid er a rooted binary tree whose root node is the triangle containing side v0vn, whose internal nodes are the nodes of the dual tree, and whose leaves Lecture Notes 20 CMSC 451 k i k j n vj i v v

v 0 v Triangulate at cost t[i,k] at cost t[k,j] cost=w(v ,v , v ) Triangulate Fig. 12: Triangulations and tree structure. correspond to the remaining sides of the tree. Observe that partitioning the pol ygon into triangles is equivalent to a binary tree with n leaves, and vice versa. This is illustrated in Fig. 13. Note that every triangle is associated with an internal node of the tree and every edge of the original polygon, except for the distinguished starting side v0vn, is associated with a leaf node of the tree. v11 1 2 3 4 5 6 7 8 9 10 root A6 root v v v v v v v v v v v0 A1 A2 A A4 A5 A7 3 A8 A9A10A11 A9 A8 A7 A6 A5 A2 A1 A4 A3 A11 A10 Fig. 13: Triangulations and tree structure. Once you see this connection. Then the following two observations follow easily. Observe that the associated binary tree has n leaves, and hence (by standard results on binary trees) n − 1 in ternal nodes. Since each internal node other than the root has one edge entering it, there are n−2 edges be tween the internal nodes. Each internal node corresponds to one triangle, and each edge between internal nodes corresponds to one chord of the triangulation.

Lecture 7: Greedy Algorithms: Activity Selection and Fractional Knapack Read: Sections 16.1 and 16.2 in CLRS. Greedy Algorithms: In many optimization algorithms a series of selections need t o be made. In dynamic programming we saw one way to make these selections. Namely, the optimal solution is describ ed in a recursive manner, and then is computed “bottom-up”. Dynamic programming is a powerful technique, but i t often leads to algorithms with higher than desired running times. Today we will consider an alternative de sign technique, called greedy algorithms. This method typically leads to simpler and faster algorithms, but it is not as powerful or as widely applicable as dynamic programming. We will give some examples of problems that can be solved by greedy algorithms. (Later in the semester, we will see that this technique can b e applied to a number of graph problems as well.) Even when greedy algorithms do not produce the optimal soluti on, they often provide fast heuristics (nonoptimal solution strategies), are often used in finding good appr oximations. Lecture Notes 21 CMSC 451 Activity Scheduling: Activity scheduling and it is a very simple scheduling prob lem. We are given a set S = f1; 2; : : : ; ng of n activities that are to be scheduled to use some resource, where each activity must be started at a given start time si and ends at a given finish time fi. For example, these might be lectures that are to be given in a lecture hall, where the lecture times have been set up in advance, or requests for boats to use a repair facility while they are in port. Because there is only one resource, and some start and finish times may overlap (and two lectures cannot be given in the same room at the same time), not all the requests can be honored. W e say that two activities i and j are noninterfering if their start-finish intervals do not overlap, more formal ly, [si; fi) \ [sj; fj) = ;. (Note that making the intervals half open, two consecutive activities are not consider ed to interfere.) The activity scheduling problem is to select a maximum-size set of mutually noninterfering ac tivities for use of the resource. (Notice that goal here is maximum number of activities, not maximum utilization. Of course different criteria could be considered, but the greedy approach may not be optimal in general.) How do we schedule the largest number of activities on the resource? Intuitively , we do not like long activities, because they occupy the resource and keep us from honoring other requests. This suggests the following greedy strategy: repeatedly select the activity with the smallest duration (fi − si) and schedule it, provided that it does not interfere with any previously scheduled activities. Although this seems like a reasonable strategy, this turns out to be nonoptimal. (See Problem 17.1-4 in CLRS). Sometimes the design of a co rrect greedy algorithm requires trying a few different strategies, until hitting on one that works. Here is a greedy strategy that does work. The intuition is the same. Since we do not like activities that take a long time, let us select the activity that finishes first and schedule it. Then, we skip all activities that interfere with this one, and schedule the next one that has the earliest finish time, and so on. To make the selection process

n]) { // given start and finish times // we assume f[1. th at is.faster. Event 1 is scheduled first. f1 f2 : : : fn. Skip 5. Then Event 4 is scheduled. The most costly ac tivity is that of sorting the activities by finish time. we assume that the activities have been sorted by their finish times. prev = i // schedule i next } return A } It is clear that the algorithm is quite simple and efficient.3 Input: 3 2 3 2 3 5 6 2 7 7 5 Add 1: 7 6 7 . 14 shows an example. Observe that the intervals are sorted by fini sh time. The output is the list A of scheduled activities. Note that this is not the only optimal schedule. Skip 2. 4. so the total running time is (n log n). Greedy Activity Scheduler schedule(s[1. 4. Assuming this sorting. and it intereferes with the remaining activity.n] already sorted List A = <1> // schedule activity 1 first prev = 1 for i = 2 to n if (s[i] >= f[prev]) { // no interference? append i to A. the pseudocode for the rest of the algorithm is presented below. activity 7 is scheduled.. The variable prev holds the index of the most recently scheduled activity at any time. Lecture Notes 22 CMSC 451 4 1 4 1 1 Add 7: Sched 7. The final output i s f1. Each activity is represented by its start-finish time interval. Fig.. It interferes with activity 5 and 6. 7g. Suppose that you have any nongreedy solution.n]. Skip 8 Sched 4. in order to determine interferences.6 Sched 1.. Finally. Proofs of optimality for greedy algorithms follow a similar structure. f2. 7g is also optimal. f[1. and then using induction to show that the rest of the choices res ult in an optimal schedule. Proof of Optimality: Our proof of optimality is based on showing that the first choice made by the algorithm is the best possible. It interferes with activity 2 and 3.

x2. We will construct a new optimal schedule A0 that is in some sense “greedier” than A. xki: 1 5x 4 G: x1 x2 A: x x2 x3 x g3 A’: x g3 1 x2 x4 x5 Fig. gj. : : : . Show that its cost can be reduced by being “greedier” at some point in the solution.Add 4: 8 4 8 6 5 4 2 1 3 5 8 8 6 Fig. The ith item is worth vi . and it does not conflict with later activities. xj−1. and therefore A0 Lecture Notes 23 CMSC 451 is also optimal. (See Fig. Consider the modified “greedier” schedule A0 that results by replacing xj with gj in the schedule A. 7g. This proof is complicated a bit by the fact that there may be multiple solutions. since other wise G would have more activities than the optimal schedule. Since A is not the sa me as the greedy schedule. Thus. That is.) It has the same number of act ivities as A. G is also optimal. : : :i where gj 6= xj . Therefore. A 0 = hx1. Order the activities in increas ing order of finish time. This is a feasible schedule.) That is. which would be a contradiction. without decreasing the number of activities. xki be the activities of A. and finds n items which can be taken. without decreasing the number of activities. 4. 15. : : : . Claim: The greedy algorithm gives an optimal solution to the activity scheduling problem. we will eventually convert A into G. 15: Proof of optimality for the greedy schedule (j = 3). Proof: Consider any optimal schedule A that is not the greedy schedule. the gr eedy schedule is of the form G = hx1. gj. : : : . we know that gj does not conflict with any earlier activity. and it finishes before xj . x2. Fractional Knapsack Problem: The classical (0-1) knapsack problem is a famous op timization problem. xj−1. xj+1. Our approach is to show th at any schedule that is not greedy can be made more greedy. (Since gj cannot conflict with the earlier activiti es. consider the first activity xj where these two schedules differ. : : : . because it finishes before xj . A thief is robbing a store. Let A = hx1. By repeating this process. (Note that k j.) The greed y algorithm selects the activity with the earliest finish time that does not conflict with any earlier a ctivity. The final s chedule is f1. x2. 14: An example of the greedy algorithm for activity scheduling.

Intuitively. b ut the thief is allowed to take any fraction of an item for a fraction of the weight and a fraction of the value. As in the case of the other greedy algorithms we have seen. However. At some point there is an item that does not fit in the remaining space. and add them in this order. you may want to ship some subset of items on a truck of limited capacity. He wants to take as valuable a load as possible. So . you might think of each object as being a sack of gold. . Let i = vi=wi denote the val ue-per-pound ratio.dollars and weighs wi pounds. in the fractional knapsack problem the setup is exactly the same. It is not possible to take a fracti on of an item or multiple copies of an item.0 3. the idea is to find the right order in which to process items. which you can partially empty out before taking. This is illustrated in Fig. If the item fits. there is a very simple and efficient greedy algorithm for the fractional knapsack problem. For example. Greedy solution to to 0−1 problem. 16 40 20 20 30 20 5 + 5 \$30 \$270 + \$100 \$140 r= 40 35 5 10 20 30 40 knapsack 6. In contrast.0 2. it is good to have high value and bad to have high weight.0 4. but only one works.) This optimization problem arises in industrial packing applications. We take as much of th is item as possible. thus filling the knapsack entirely. There are a few choices that you might try here. The 0-1 knapsack problem is hard to solve. we take it all. and in fact it is an NP-complete prob lem (meaning that there probably doesn’t exist an efficient solution). b ut has a knapsack that can only carry W total pounds.0 5. Which items should he take? (The reason that this is calle d 0-1 knapsack is that each item must be left (0) or taken entirely (1). where vi and wi are integers. We sort the items in decreasing order of i.0 \$30 60 \$30 \$20 \$100 \$90 \$160 fractional problem. T his suggests that we first sort the items according to some function that is an decreases with value and increases w ith weight.

Given a room with sacks of gold. you would obviously take as much gold as possible. Consider the first item i on which the two selections differ. then you could take the items of weigh ts 20 and 40 for a total value of \$100 + \$160 = \$260. Huffman Codes: Huffman codes provide a method of encoding data efficiently.Greedy solution to 0−1 problem. because its is very easy to brea k a string up into its individual characters.3 in CLRS. Let us say that greedy takes x more Lecture Notes 24 CMSC 451 units of object i than the alternate does. and then (since the item of weight 40 does not fit) you would settle for the item of weight 30. then 20. a contradiction. silver. this implies that the alternate selection is not o ptimal. On the othe r hand. More formally. Norm ally when characters are coded using standard codes like ASCII. for a total value of \$30 + \$100 + \$90 = \$220. However. and then as much bronze as possible. Lecture 8: Greedy Algorithms: Huffman Coding Read: Section 16. then you would first take the items of weight 5. and ignored the item of weight 5. if you had been less greedy. and to access individual characters and substrings by direct indexin g. By definition. each character is represented by a fixed-length codeword of bits (e. But it would never bene fit you to take a little less gold so that you could replace it with an equal volume of bronze. Optimal solution Input \$100 \$90 + + \$220 \$260 \$160 + \$100 Fig. Sort the items of the alternate selectio n in decreasing order by values. suppose to the contrary that the greedy algorithm is not optimal. Consider the example shown in Fig. This would mean that there is an alternate selection that is optimal.g. 16. 8 bits per character). . By replacing x units of any such items with x units of item i. All the subsequent elements of the al ternate selection are of lesser value than vi. Fixed-length codes are popular. Nonoptimality for the 0-1 Knapsack: Next we show that the greedy algorithm is no t generally optimal in the 0-1 knapsack problem. gre edy takes a greater amount of item i than the alternate (because the greedy always takes as much as it can). If you were to sort the items by i. fixed-length codes may not be the most efficient from the perspective of minimizing the total quant ity of data. 16: Example for the fractional knapsack problem. we would increase the overall value of the alternate selection. Correctness: It is intuitively easy to see that the greedy algorithm is optimal for the fractional problem. and bronze. This feature of “delaying gratification” in order to come up wit h a better overall solution is your indication that the greedy solution is not optimal. then take as much silver as possible. However.

once encoded. the length of the encoded string is j ust 2n bits. the resulting 17-character string would be “01100101110010010”. In fact.05 0. assuming that the probabilities of character occur rences are known. More generally. Prefix Codes: One issue that we didn’t consider in the example above is whether we will be able to decode the string.05 Variable-Length Codeword 0 110 10 111 Notice that there is no requirement that the alphabetical order of character cor respond to any sort of ordering applied to the codewords. Character a b c d Probability 0. we would like the code to have the property that it can be uniquely decoded. (This might happen by analyzing many strings over a long period of time. For example. In applications like data compression. what would be the expected savings for a string of length n? For the 2-bit fixed-length code. c. Suppose that instea d of coding the character ‘a’ as 0. this would represent a 25% savings in expected encoding length. the expected length of a single encoded character is equal to the sum of c ode lengths times the respective probabilities of their occurrences.) You can use this knowledge to encode strings differently. where you want to encode one file. a b a c d a a c a c 0 110 0 10 111 0 0 10 0 10 Lecture Notes 25 CMSC 451 Thus. Now. Thus. you can just scan the file and determine the exact frequencies of all the characters. It might b e “d” and it might be “aaa”. by using this alternative code. the same string would be encoded as follows. a b a c d a a c a c 00 01 00 10 11 00 00 10 00 10 The final 20-character binary string would be “00010010110000100010”. Frequently occurring characters are enc oded using fewer bits and less frequent characters are encoded using more bits. n(0:60 1 + 0:05 3 + 0:30 2 + 0:05 3) = n(0:60 + 0:15 + 0:60 + 0:15) = 1:5n: Thus. b. but this will tend to lengthen the encoding. The questi on that we will consider today is how to form the best code. we have achieved a savings of 3 characters. Note that in both the variable-length codes given in the example above no codewo . Instead. Now. For the variable-length code. which is un desirable. We could design a variable-length code which w ould do a better job. the encoded string “111” is ambiguous.30 0. dg. Now. we had encoded it as 1. suppose that you knew the relative probabilities of characters in advance.60 0. suppose that chara cters are expected to occur with the following probabilities.Consider the following example. We could use the following fixed-length code: Character a b c d Fixed-Length Codeword 00 01 10 11 A string such as “abacdaacac” would be encoded by replacing each of its characters b y the corresponding binary codeword. How can we avoid this sort of ambiguity? You might suggest that we add separa tion markers between the encoded characters. The expected encoded string length is just n times the expected encoded character length. Suppose that we want to encode strings over the (rather limited) 4-character alphabet C = fa. this code was chosen quite carefully.

It was invented in the mid 1950’s by David Huffman. This turns out to be the key property. Decoding a prefix code is simple. we can determine the total length of the encoded text. and its corresponding tree is shown in the following figure. 17: Prefix codes. Observe that any binary prefix coding can be described by a binary tree in which the codewords are the leaves of the tree. The e xpected number of bits needed to encode a text with n characters is given in the following formula: B(T) = n X x2C p(x)dT(x): Lecture Notes 26 CMSC 451 This suggests the following problem: Optimal Code Generation: Given an alphabet C and the probabilities p(x) of occur rence for each character x 2 C. then we know that we may decode this without fear of it matching some longer codeword. Note that the optimal code is not unique. Prefix Code: An assignment of codewords to characters so that no codeword is a p refix of any other. compute a prefix code T that minimizes the expected length of the encoded bit-string. For example.rd is a prefix of another. (There are better co .g. and is called a Huffman code. On reaching a leaf. The code given earlier is a prefix code. The length of a codeword is just its depth in the tree. a ! 001 and b ! 00101. Thus we have the following definition. B(T). then as soon as we see a codeword appearing as a prefix in the encoded text. then when we see 00101 : : : how do we know whether the first charact er of the encoded message is a or b. 110 111 10 0 0 0 1 1 0 1 b d c a Fig.. Conversely. We just traverse the tree from root to leaf. we could have complemente d all of the bits in our earlier code without altering the expected encoded string length. Observe that if two codewords did share a comm on prefix. Expected encoding length: Once we know the probabilities of the various characte rs. The code gi ven earlier is shown in the following figure. and let dT (x) denote the length of the codeword (depth in the tree) relative to some prefix tree T. we output the corresponding charact er. and where a left branch means “0” and a right branch means “1”. and return to the root to continue the process. There is a very simple algorithm for finding such a code. By the way. if no codeword is a prefix of any other. this code is used by the Unix utility pack for file compression. e. Let p(x) denote the probability of seeing character x. l etting the input character tell us which branch to take.

Then. meaning that every internal node has exactly two children. Another way to think of this. T hen we continue recursively building the code on the new alphabet. we know the code for z. The resulting tree is the final prefix tree. Our approach will be to show that any tree that differs from the on e constructed by Huffman’s algorithm can be converted into one that is equal to Huffman’s tree withou t increasing its cost. Since x and y will appear at the bottom of the tree. The objects in Q are sorted by probability. and th is is the root of the final prefix code tree. Claim: Consider the two characters. Recall that this data structure can be built initially in O(n) time. compress. The result is Huffman’s algorithm. and let b and c be two siblings at the maximum depth of the tree. gzip and many others are based on a more sophisticated method called the Lempel-Ziv coding. The character z will have a probability equal to the sum of x and y’s probabilities. The n there is an optimal code tree in which these two characters are siblings at the maximum depth in the tree. which then replaces x an d y in the alphabet. so we may limit consideration to full binary trees. an d we can extract the element with the smallest key in O(log n) time and insert a new element in O(log n) time. is that we merge x and y as the left and right chi ldren of a root node called z. Then the subtree for z replaces x and y in the list of characters. When the p rocess is completed.mpression methods however. since x and y have the two smallest probabilities it fol lows that p(x) p(b) and .) Huffman’s Algorithm: Here is the intuition behind the algorithm. It would never pay to have an internal node with only one child (since such a node could be deleted). which has one fewer character. Proof: Let T be any optimal prefix code tree. after n − 1 iterations. We repeat this pro cess until only one super-character remains. Recall that we ar e given the occurrence probabilities for the characters. Each character x 2 C is associated with an occurrence probability x:prob. we append a 0 and 1 to this codeword. Let C denote the set of cha racters. say 010. the number of items in the queue decreases by one. there is exactly one element left in the queue. The pseudocode for Huffman’s algorithm is given below. First. the charac ters are all stored in a priority queue Q. Assume without loss of generality that p(b) p(c) and p(x) p(y) (if this is not true. Initially. So. x and y with the smallest probabilities. and “merge” them into a single super-character called z. it seem most logical to select the two characters with the smallest probabilities to per form the operation on. It is illustrated in the following figure. We are going to build the tree up from the leaf level. Correctness: The big question that remains is why is this algorithm correct? Rec all that the cost of any encoding tree T is B(T) = P x p(x)dT(x). Note that with each execution of the for-loop. Now. then rename these characters). given 0100 for x and 0101 for y. observe that the Huffman tree is a full binary tree. For example. We wi ll take two characters x and y.

and hence their product is nonnegative. Almost all the nodes contribute the same to the expected cost. Now switch the positions of x and b in the tree. Next let us see how the cost changes as we go from T to T0. By subtracting the o ld contributions of these Lecture Notes 27 CMSC 451 30 b: 48 d: 17 f: 13 smallest smallest smallest smallest 22 12 a: 05 c: 07 e: 10 b: 48 d: 17 f: 13 30 smallest 52 b: 48 22 12 a: 05 0 b: 48 Final Tree 011 1 010 0 1 1 1 0 0 1 001 0001 1 0 0000 d: 17 f: 13 a: 05 c: 07 e: 10 e: 10 d: 17 f: 13 c: 07 e: 10 a: 05 c: 07 12 22 12 a: 05 c: 07 b: 48 d: 17 e: 10 f: 13 .) Because b and c are at the deepest level of the tree we know that d(b) d(x) and d(c) d(y). (In both cases they may be equal. The only exception are nodes x and b. they may be equal. (Again.p(y) p(c). This is illustrated in the following figure. we have p(b ) − p(x) 0 and d(b) − d(x) 0.) Thus. resulting in a new tree T0.

Suppose we have exactly n characters. By switch ing y with c we get a new tree T00. We want to show it is true with exactly n characters. Thus the cost does not increase. // priority queue for i = 1 to n-1 { z = new internal tree node. The above theorem asserts that the first step of Huffman’s algorithm is essentiall y the proper one to perform.prob. the two characters of . } T’’ −(p(b)−p(x))(d(b)−d(x)) Cost change = < 0 Cost change = −(p(c)−p(y))(d(c)−d(y)) < 0 T T’ x y c y x c b b c y b x Fig. z. // extract smallest probabilities z. the tree consists of a single leaf node.prob + y. Claim: Huffman’s algorithm produces the optimal prefix code tree. // z’s probability is their sum Q.insert(z).prob = x.n]) { Q = C.extractMin(). For the basis c ase. the number of characters. Lecture Notes 28 CMSC 451 Huffman’s Algorithm Huffman(int n.left = x = Q. Assume inductively that when strictly fewer than n characters. Proof: The proof is by induction on n. implying that T 0 is an optimal tree. z. // insert z into queue } return the last element left in Q as the root.a: 05 b: 48 c: 07 d: 17 e: 10 f: 13 Fig. The complete proof of correctness for Huffman’s algorithm follows by induction on n (since with each step. 18: Huffman’s Algorithm. nodes and adding in the new contributions we have B(T 0) = B(T)−p(x)d(x) + p(x)d(b)−p(b)d(b) + p(b)d(x) = B(T) + p(x)(d(b) − d(x)) − p(b)(d(b) − d(x)) = B(T) − (p(b) − p(x))(d(b) − d(x)) B(T) because (p(b) − p(x))(d(b) − d(x)) 0. 19: Correctness of Huffman’s Algorithm. which is obviously optimal..extractMin(). we eliminate exactly one character). n = 1. The final tree T00 satisf ies the statement of the claim. Huffman’s algorithm is guaranteed to produce the optimal tree. character C[1.right = y = Q. The previous claim states that we may assume that in the optimal tre e. which by a similar argument is also optimal.

any time you have a set of objects. surface meshes used for shape description in computer-aided design and geographic inform ation systems. Graphs and Digraphs: Most of you have encountered the notions of directed and un directed graphs in other courses. (Another way of saying thi s is that E is a binary relation on V . Consider any prefix code tree T made with this new set of n−1 characters. By indu ction. Thus n − 1 charact ers remain.1 and 22. 1 3 4 1 2 3 2 4 . precedence constraints in scheduling systems.) Observe that self-loops are allowed by this definition. Most of the problems in computational graph theory that we will consider arise b ecause they are of importance to one or more of these application areas. The cost of the new tree is B(T 0) = B(T)−p(z)d(z) + p(x)(d(z) + 1) + p(y)(d(z) + 1) = B(T)−(p(x) + p(y))d(z) + (p(x) + p(y))(d(z) + 1) = B(T) + (p(x) + p(y))(d(z) + 1−d(z)) = B(T) + p(x) + p(y): Since the change in cost depends in no way on the structure of the tree T. we need to build the tree T on n − 1 characters optimally. many of these problems f orm the basic building blocks from which more complex algorithms are then built. and th ere is some “connection” or “relationship” or “interaction” between pairs of objects. to mi nimize the cost of the final tree T 0. Lecture 9: Graphs: Background and Breadth First Search Read: Review Sections 22. and E. Basically. Graph Algorithms: We are now beginning a major new section of the course. connected by a collection of edges. Graphs are extremely important because they are a very flex ible mathematical model for many application problems. We can c onvert it into a prefix code tree T0 for the original set of characters by undoing the previous operatio n and replacing z with x Lecture Notes 29 CMSC 451 and y (adding a “0” bit for x and a “1” bit for y). this exactly what Huffman’s algorithm does. called the vertices or nodes. VLSI and other so rts of logic circuits. Some definitions of grap hs disallow this. a graph is a good way to model this. Exam ples of graphs in application include communication and transportation networks. The list of application is almost too long to even consider enumerating it. a set of ordered pairs. Multiple edges are not permitted (although the edges (v. Intuitively. Thus the final tree is optimal.2 CLR. We wil l be discussing algorithms for both directed and undirected graphs. Definition: A directed graph (or digraph) G = (V. replacing them with a new character z whose probability is p(z) = p(x) + p(y).E) consists of a finite set V .w) and (w. Rem ove x and y. Furthermore. v) are distinct). called the edges of G. a graph is a collection of ver tices or nodes. so we will give a quick overview here.lowest probability x and y will be siblings at the lowest level of the tree.

otherwise. However. v). k.Digraph Graph Fig. Definition: An undirected graph (or graph) G = (V. In a di rected graph.2. Certain notions (such as path) are defined for both. We say that vertex v is adjacent to vertex u if there is an edge (u. A cycle is a path containing at least one edge and for w . v1 . and the number of edges is written as m or E or e. Sum of degrees: P v2V in-deg(v) = P v2V out-deg(v) = E: Notice that generally the number of edges in a graph may be as large as quadrati c in the number of vertices. Here are some basic combinatorial facts about graphs and digraphs. The number of vertices is typically written as n or V . By the degree of a graph. we typically consider both the number of ve rtices and the number of edges. vki such that (vi−1. : : : . The length of the path is the number of edges. Lecture Notes 30 CMSC 451 Note that directed graphs and undirected graphs are different (but similar) obje cts mathematically. Given a graph with V vertices and E edges then: In a graph: Number of edges: 0 E n 2 = n(n − 1)=2 2 O(n2): Sum of degrees: P v2V deg(v) = 2E: In a digraph: Number of edges: 0 E n2. vi) is an edge for i = 1. Paths and Cycles: A path in a graph or digraph is a sequence of vertices hv0. In a digraph. 20: Digraph and graph example. A path is simple if all vertices and all the edges are distinct. A graph is said to be sparse if E 2 (V ). When discussing the size of a graph. we say that u is the origin of e and v is the destination of e. : : : . we usually mean the maxi mum degree of its vertices. When giving the running times of algorithms. In u ndirected graphs u and v are the endpoints of the edge. so that the performance on sparse and dense graphs wil l be apparent.E) consists of a finite set V of vertices. and the number of edges coming in is called the in-degree. given the edge e = (u. and a set E of unordered pairs of distinct vertices. v). We will leave the proofs to you. called the edges. but other notions (such as connecti vity) may only be defined for one. the large graphs that arise in practice typically have much fewer edges . The edge e is incident (meaning that it touches) both u a nd v. k. (Note that self-loops ar e not allowed). the number of edges coming out of a vertex is called the out-degre e of that vertex. we w ill usually express it as a function of both V and E. In an undirected graph we just talk about the degree of a vertex as the number of incident edges. or may be defined differently. and dense.

w) =2 E then generally W(v.) The subsets of mutually reachable vertices partition the vertices of the graph into disjoint subsets. (By 1 we mean (in practice) some number which is larger than any allowable weight.w) (the weight on edge (v. In practice. We will assume that the vertices of G are indexed f1. e. (Connectivity is a bit messier for digraphs. but often we set it to some “special” value.w) 2 E 0 otherwise. A(v. called the c onnected components of the graph. the vertices that can be reached from v by a single edge).w] = 1 if (v. A graph or digraph is said to be acyclic if it contains no simple cycles. 21: Illustration of some graph terms.w)).w) need not be defined. For example i f (v.g. If (v. 3 1 1 1 0 0 1 1 0 0 2 3 . We say that w is reachable from u if there is a path from u to w. A cycle is simple if its vertices (except v0 and vk) are distinct. : : : . Adj[v] poin ts to a linked list containing the vertices which are adjacent to v (i.) An acyclic un directed graph (which need not be connected) is a collection of free trees.w] = W(v. If the digraph has weights we can store the weights in the matrix.) Adjacency List: An array Adj[1 : : : n] of pointers where for 1 v n. A[v. If the edges have weights then these weights may also be stored in the linked list elements. Let G = (V.E) be a digraph with n = jV j and let e = jEj. and is (naturally) called a forest. An acyclic digraph is called a directed acyclic graph. ng. First we show how to represent digraphs.e.w) = −1. Adjacency Matrix: An n n matrix defined for 1 v.hich v0 = vk. An acy clic connected graph is called a free tree or simply tree for short. th is might be some machine dependent constant like MAXINT.w) 2 E then A[v. or 1. or DAG for short. An undirected graph is connected if ever y vertex can reach every other vertex. Free Tree cycle Simple cycle Nonsimple Forest DAG Fig. Lecture Notes 31 CMSC 451 Representations of Graphs and Digraphs: There are two common ways of representin g graphs and digraphs. as is usually seen in data structures. (The term “free” is intended to emphasize the fa ct that the tree has no root.w n. Note that ever y vertex is reachable from itself by a trivial path that uses zero edges. 2. in contrast to a rooted tree. and we will define it later . and all its edges are distinct.

while (Q is nonempty) { u = Q.Dequeue() // u is the next to visit for each v in Adj[u] { if (color[v] == white) { // if neighbor v undiscovered color[v] = gray // ...mark it discovered d[v] = d[u]+1 // ...set its distance pred[v] = u // ...and its predecessor Q.Enqueue(v) // ...put it in the queue } } color[u] = black // we are done with u } } Observe that the predecessor pointers of the BFS search define an inverted tree (an acyclic directed graph in which the source is the root, and every other node has a unique path to the root ). If we reverse these edges we get a rooted unordered tree called a BFS tree for G. (Note that there are many p otential BFS trees for a given graph, depending on where the search starts, and in what order vertices are plac ed on the queue.) These edges of G are called tree edges and the remaining edges of G are called cross edges. It is not hard to prove that if G is an undirected graph, then cross edges alway s go between two nodes that are at most one level apart in the BFS tree. (Can you see why this must be true?) Below is a sketch of a proof that on Lecture Notes 33 CMSC 451 Q: a, c, d Q: c, d, e Q: d, e, b Q: (empty) Q: b, f, g Q: e, b 1 1 1 1 2 1 0 1 1 a e 2 b c d s c e b 1 2 2 0 s g c e f a d b b, f, g e d s a c 3 3 1 1 1 2 2 2 1 1 b b a c d

As done in CLR V = jV j and E = jEj. the number o f times we go through the while loop is at most V (exactly V assuming each vertex is reachable from the source). Observe that the initialization portion req uires (V ) time. Sin ce v is a neighbor of u. d[v] is equal to the distance from s to v.) Theorem: Let (s. Le t u be the predecessor of v on some shortest path from s to v. u) + 1 = (s. 24: Breadth-first search: Example. v) = (s. u).2 and 23. (See the CLRS for a deta iled proof. (The +1 is because eve n if deg(u) = 0.3 in CLR. we need to spend a constant amount of time to set up the loop.) Summing up over all vertice s we have the running time T(V ) = V + X u2V (deg(u) + 1) = V + X u2V deg(u) + V = 2V + 2E 2 (V + E): The analysis is essentially the same for directed graphs. Since we never visit a vertex twice. Proof: (Sketch) The proof is by induction on the length of the shortest path. The real meat is in the traversal loop. Lecture Notes 34 CMSC 451 Lecture 10: Depth-First Search Read: Sections 23. and among all such vertices the first to be proc essed by the BFS. (s. u) + 1. v). v) denote the length (number of edges) on the shortest path from s to v. Thus. Analysis: The running time analysis of BFS is similar to the running time analys is of many graph traversal algorithms. Thus we have d[v] = d[u] + 1 = (s. we have (by induction) d[u] = (s. termination. on termination of the BFS procedure. and it has the nice . as desired. d[v] = (s. When u is processed. we set d[v] = d[u] + 1.s 0 a 1 1 c 1 d s f a d 0 s 2 1 1 e a c d s 0 3 3 e 2 f g a c d 0 s e g Fig. Then. Depth-First Search: The next traversal algorithm that we will study is called de pth-first search. The number of iterations through the inner for loop is proportional to deg(u) + 1. v).

The same algorithm works for undirected graphs (but the resulting structure imposed on the graph is diffe rent).visit v } color[u] = black.property that nontree edges have a good deal of mathematical structure. // we’re done with u f[u] = ++time.. Depth-First Search DFS(G) { // main program for each u in V { // initialization color[u] = white. When you return to the same room. // . then backtrack. } Analysis: The running time of DFS is (V + E). and black means finished.) The algorithm is shown in code block below. As with BFS. when you ent er a new room. When all doors have been tried in a given room..E) . Depth-First Search Algorithm: We assume we are given an directed graph G = (V. As befor e we also store predecessor pointers. (Note: Do not confuse the discovery time d[v] with the distance d[v] from BFS. 25. As before we maintain a color for each vertex: whi te means undiscovered. try a different door leaving the room (assuming it goes somewhere you haven’t already been). We use four auxiliary arrays. To solve it you might u se the following strategy. // . We will discuss this tree structure further below. We will al so associate two numbers with each vertex. Successively travel from room to room as long as you come to a place you haven’t a lready been. This is the general idea behind depth-first search.. As you enter a room of the castle. This is somewhat harder to see than the BFS analysis. // start a new search here } DFSVisit(u) { // start a search at u color[u] = gray. DFS induces a tree structu re. pred[u] = null. // mark u visited d[u] = ++time. Consider the problem of searching a castle for treasure. paint some graffiti on the wall to remind yourse lf that you were already there. In particular. and illustrated in Fig. pointing back to the vertex that discovered a given vertex. for each v in Adj(u) do if (color[v] == white) { // if neighbor v undiscovered pred[v] = u. Notice that this algorithm is described recursively. because the recursive nature of the algorithm obscures things. When we first discover a vertex u store a co unter in d[u] and when we are finished processing a vertex we store a counter in f[u].. you are beginning a new search. Normally. These are time stamps. } time = 0. recurrences are goo d ways to analyze recursively Lecture Notes 35 CMSC 451 3/4 . The purpose of the time stamps will be explained later.set predecessor pointer DFSVisit(v). gray means discovered but not finished processing. for each u in V if (color[u] == white) // found an undiscovered vertex DFSVisit(u).

7/... 6/..2/5 3/4 f 2/. 3/4 6/9 7/8 12/13 11/14 return g return f DFS(d) return a DFS(e) return e return f DFS(a) DFS(b) DFS(c) 3/4 g a b c f g d e 1/10 6/9 7/8 2/5 1/10 2/5 b c a d e . a b c 1/... b c a b c f g 1/.. 2/5 DFS(f) DFS(g) f c b a return b return c 3/.

. v 2 V . v) where u and v are not ancestors or descendents of one anothe r (in fact. Observe that each vertex is visited exactly once in the search. f[v]]. f[u]] and [d[v]. (Can you see why not?) Lecture Notes 36 CMSC 451 Time-stamp structure: There is also a nice structure to the time stamps. So. With undirected graphs. f[v]] are disjoint. Thus the total time used in the procedure is T(V ) = V + X u2V (outdeg(u) + 1) = V + X u2V outdeg(u) + V = 2V +E 2 (V + E): A similar analysis holds if we consider DFS for undirected graphs. This is just the recursion tree. v) arises when processing vertex u we call DFSVisit(v) for some neighbor v. the following are easy to observe. there are some important differences in the structure of the DFS tree. it can be shown that there can be no cross edges. It is not difficult to classify the edges of a DFS tree by analyzing the values of colors of the vertices and/or considering the time stamps. 6/9 11/14 2/5 12/13 . Cross edges: (u. u is a descendent of v if and only if [d[u]. Tree structure: DFS naturally imposes a tree structure (actually a collection of trees. f[u]] [d[v]. In particular. Lemma: (Parenthesis Lemma) Given a digraph G = (V. we can see that each vertex u can be processe d in O(1+outdeg(u)) time. by convention.E). and any DFS tree for G and any two vertices u. where the edge (u. First observe that if we ignore the time spent in the recursive calls. This is left as an exercise. Fig. a self-loop is considered to be a back edge). First. u is an ancestor of v if and only if [d[u]. For directed graphs the other edges of the grap h can be classified as follows: Back edges: (u. the edge may go between different trees of the forest). (Thus. the main DFS procedure runs in O(V ) time. they ar e all called back edges by convention. v) where v is a proper descendent of u in the tree. there is really no distinction between forward and back edges.g a 1/. In CLR this is referred to as the parenthesis structure. v) where v is a (not necessarily proper) ancestor of u in the tr ee. Ignoring the time spent in the recursive calls. but it is not true here. 25: Depth-First search tree. f[v]]. Forward edges: (u. f[u]] [d[v]. defined algorithms. Furthermore. We can just analyze each one individually and add up their running times. and hence the ca ll DFSVisit() is made exactly once for each vertex. u is unrelated to v if and only if [d[u]. because there is no good notion of “s ize” that we can attach to each recursive call. or a forest) on the structure of the graph.

v is a descendent of u. the proof follows directly from the pa renthesis lemma. When we were processing u. 26: Parenthesis Lemma. But you should not infer that there is so me simple relationship . (E. Thus along any path . You can determin e whether the graph contains any cycles very easily. implying there can be no cycle. Beware: No back edges means no cycles. suppose you are given a graph or digraph. Suppose there are no back edges. Because the intervals are disjoint. You run DFS. and by fo llowing tree edges from v to u we get a cycle. v was not white (otherwise (u. If the edge is a back edge then f[u] f[v]. G has a cycle if a nd only the DFS forest has a back edge. v). Proof: For tree. Proof: (() If there is a back edge (u. Lemma: Consider a digraph G = (V. v) would be a tree edg e).8 1/10 9 10 11 12 13 14 F C C 7/8 1 2 3 4 5 6 7 a c b f d e g 3/4 B C e d g f c b a Fig. consider any DFS forest of G. By the lemma ab ove. ()) We show the contrapositive.E) and any DFS forest for G. for a forward edge (u. v) we know that the two time intervals are disjoint. Cycles: The time stamps given by DFS allow us to determine a number of things ab out a graph or digraph.g. then f[u] > f[v]. and back edges. and so v’s start-finish interval is c ontained within u’s. implying that v was started before u. v must have also finished before u. and cross all have the property that th ey go from vertices with higher finishing time to vertices with lower finishing time.E). or cross edge. then v is an ancestor of u. forward. forward. For example. tree.) For a cross edge (u. each of the remaining types of edges. forward. We do this with the help of the following two l emmas. v) 2 E. and consider any edge (u. Lemma: Given a digraph G = (V. v). If this edge is a tree. finish times decrease monotonically. implying that v has an earlier finish time.

jacket 7/8 2/9 1/10 4/5 3/6 11/14 15/16 12/13 shirt shirt jacket tie shoes pants shorts tie belt shoes socks belt pants shorts socks Fig.c . th en the resulting digraph. v 2 V .Strong Components: Next we consider a very important connectivity problem with d igraphs. we say that two vertices u and v are mutually reachabl e if u and reach v and vice versa. belt. u can reach v and vice versa . In fact we will solve a generalization of this problem. Th is equivalence relation partitions the vertices into equivalence classes of mutually reachable vertices. and these are the strong components.i a. 27: Topological sort. pants. We would like to write an algorithm that determines whether a digraph is strongl y connected. property. we may be accurately refer to it as the component DAG.g. a b c d e f d. tie. Observe that if we merge the vertices in each strong component into a single sup er vertex.e f. shorts. we partition the vertices of the digraph into subsets such that the induced subgraph of each subset is strongly connected. A digraph is strongly connected if for every pair of vertices. and joint two supervertices (A. (These subsets should be as large as possible. is necessarily acyclic. In particular. and still have this Lecture Notes 38 CMSC 451 jacket Final order: socks. v) 2 E.B) if and only if there are vertices u 2 A and v 2 B such that (u.b. It is easy to see that mutual reachability is an equivalence relation. shoes. (Can you see why? ) Thus.h. of computing the strongly connected comp onents (or strong components for short) of a digraph. people want to know that ther e networks are complete in the sense that from any location it is possible to reach any other location in t he digraph. When digraphs are used in communication and transportation networks. shirt. called the component digraph. u.) More formally.

when the search is started at vertex a. That is. the answer is yes. Thus all the vertices in a strong component must appear in the same tree of the DFS forest. by v isiting components in reverse topological order of the component tree. and that is the problem we are trying to solve. By definition of DFS. We will give some of the intuition that leads to the algorithm. but it is so clever that it is very diffic ult to even see how it works. in the figure below right. (u. (This is ridiculous. consider the DFS of the digraph shown in the following figure (left). when you enter a strong component. (See the DFS on the right for a counterexample. Now. and put th em in the same DFS tree. Strong Components and DFS: By way of motivation. The algorithm that we will present is an algorithm designer’s “dream” (and an algorith m student’s nightmare). then v comes before u in this reversed order (not after a s it would in a normal topological ordering). In general. every vertex in the component is reachable. it must visit every vertex within the component (and possibly some others) before finishing. because you would need to know the strong components. Clearly once the DFS starts within a given st rong component. See CLRS for a formal proof. but will not prove the a lgorithm’s correctness formally. I f we do not start in reverse topological. run DFS. so the DFS does not terminate until all the vertices in the component have been visited. each search cannot “leak out” into other co mponents. not only does it visit its component with b and c. However.) Does there always exist a way to order the DFS such that it is true? Fortunately. Is it always true for any DFS? Un fortunately the answer is no. Observe th at in the figure each strong component is just a subtree of the DFS forest. b a c d i e g h f h . But humor me for a moment. It is amazingly simple and efficient. 28: Strong Components.) Further Lecture Notes 39 CMSC 451 suppose that you computed a reversed topological order on the component digraph. because other components would have already have been visited earlier in the search. For example. then the search may “leak out” into other strong components. Suppose that you knew the component DAG in advance.Digraph and Strong Components Component DAG i h g Fig. select the next available vertex according to this reverse topological order of the component digraph. many strong components may appear in the same DFS tree. v) is an edge in the component digraph. but the it also visits the other components as well. Here is an informal justification. but every time you need a new vertex to start the searc h from.

(After all. Given an adjacency list for G. I will present the al gorithm.c b a f g i d e 2/3 10/11 1/8 4/7 5/6 9/12 13/18 14/17 15/16 3/4 2/13 1/18 14/17 5/12 15/16 6/11 7/10 8/9 Fig. However. we are tr ying to solve the strong component problem in the first place). (I’ll leave this as an exercise. then we would have an easy algorithm f or computing strong components. it is possible to compute GR in (V + E) time. we do not know what the component DAG looks like. though. and refer you to CLRS for the complete proof. so tha t it hits the strong components according to a reverse topological order. First recall that GR (what CLRS calls GT ) is the digrap h with the same vertex set as G but in which all edges have been reversed in direction. Correctness: Why visit vertices in decreasing order of finish times? Why use the reversal digraph? It is difficult to justify these elements formally. without actually computing the component DAG. Recall that the main intent is to visit the Lecture Notes 40 CMSC 451 Strong Components StrongComp(G) { . This leaves us with the intuition that if we could somehow order the DFS. If u and v are mutually reachable in G. and all operate in (V + E) time. Here is the algorithm. Then visit the nodes of GR in decreasing order of finish times. then certainly this is still true in GR. All the steps of the algorithm are quite easy to implement. All that c hanges is that the component DAG is completely reversed. The “trick” behind the strong componen t algorithm is that we can find an ordering of the vertices that has essentially the necessary property . The ordering trick is to order the vertices of G accordi ng to their finish times in a DFS. Unfortunately it is quite difficult to understand why this algorithm works. Here is some intuition. The Plumber’s Algorithm: I call this algorithm the plumber’s algorithm (because it a voids leaks).) Observe that the strongly connected components are not affected by reversing all the digraph’s edges. 29: Two depth-first searches.

30: Strong Components Algorithm strong components in a reverse topological order. computing finish times f[u] for each vertex u. Compute R = Reverse(G). this suggests that we should visit the vertices in increasing order of finish time. starting with the lowest finishing time. Each DFS tree is a strong component. This is a good starting idea. The question is how to order t he vertices so that this is true. } d e f i h g 3 2 1 9 4 5 6 7 c a b 8 6/11 7/10 a c b d e f i g h 3/4 14/17 5/12 15/16 Initial DFS Reversal with new vertex order Final DFS with components a b c f g i h d e 8/9 1/18 2/13 Fig. and t . that in a DAG.. So. Sort the vertices of R (by CountingSort) in decreasing order of f[u].e. reversing all edges of G. the first vertex in the topological order is the one with the highest fin ish time).Run DFS(G). Recall from the topological sorting algorithm. finish times occur in reverse topological order (i. if we wanted to visit the components in reverse topological order. but it turns out that it doesn’t work. The reason is that there are many vertices in each strong component. Run DFS(R) using this order.

hey all have different finish times. For example, in the figure above observe that in the first DFS (on the le ft) the lowest finish time (of 4) is achieved by vertex c, and its strong component is first, not last, in topologica l order. It is tempting to give up in frustration at this point. But there is something t o notice about the finish times. If we consider the maximum finish time in each component, then these are related to the topological order of the component DAG. In particular, given any strong component C, define f(C) to be th e maximum finish time among all vertices in this component. f(C) = max u2C f[u]: Lemma: Consider a digraph G = (V;E) and let C and C0 be two distinct strong comp onents. If there is an (u; v) of G such that u 2 C and v 2 C0, then f(C) > f(C0). See the book for a complete proof. Here is a quick sketch. If the DFS visits C f irst, then the DFS will leak into C0 (along edge (u; v) or some other edge), and then will visit everything in C0 before finally returning to C. Thus, some vertex of C will finish later than every vertex of C0. On the other h and, suppose that C0 is visited first. Because there is an edge from C to C0, we know from the definition of the component DAG that there cannot be a path from C0 to C. SoC0 will completely finish before we even start C. Thus all the finish times of C will be larger than the finish times of C0. For example, in the previous figure, the maximum finish times for each component are 18 (for fa; b; cg), 17 (for fd; eg), and 12 (for ff; g; h; ig). The order h18; 17; 12i is a valid topologica l order for the component digraph. Lecture Notes 41 CMSC 451 This is a big help. It tells us that if we run DFS and compute finish times, and then run a new DFS in decreasing order of finish times, we will visit the components in topological order. The pr oblem is that this is not what we wanted. We wanted a reverse topological order for the component DAG. So, the final trick is to reverse the digraph, by forming GR. This does not change the strong components, but it r everses the edges of the component graph, and so reverses the topological order, which is exactly what we wanted. In conclusion we have: Theorem: Consider a digraph G on which DFS has been run. Sort the vertices by de creasing order of finish time. Then a DFS of the reversed digraph GR, visits the strong components accord ing to a reversed topological order of the component DAG of GR. Lecture 12: Minimum Spanning Trees and Kruskal’s Algorithm Read: Chapt 23 in CLRS, up through 23.2. Minimum Spanning Trees: A common problem in communications networks and circuit design is that of connecting together a set of nodes (communication sites or circuit components) by a network of minimal total length (where length is the sum of the lengths of connecting wires). We assume that the network is undirected. To minimize the length of the connecting network, it never pays to have any cycles (since we could break any

cycle without destroying connectivity and decrease the total length). Since the resulting connection graph is connected, undirected, and acyclic, it is a free tree. The computational problem is called the minimum spanning tree problem (MST for s hort). More formally, given a connected, undirected graph G = (V;E), a spanning tree is an acyclic subset of edges T E that connects all the vertices together. Assuming that each edge (u; v) of G has a numeric wei ght or cost, w(u; v), (may be zero or negative) we define the cost of a spanning tree T to be the sum of edges in the spanning tree w(T) = X (u;v)2T w(u; v): A minimum spanning tree (MST) is a spanning tree of minimum weight. Note that th e minimum spanning tree may not be unique, but it is true that if all the edge weights are distinct, the n the MST will be distinct (this is a rather subtle fact, which we will not prove). Fig. 31 shows three spanning trees for the same graph, where the shaded rectangles indicate the edges in the spanning tree. The one on the left i s not a minimum spanning tree, and the other two are. (An interesting observation is that not only do the edges sum to the same value, but in fact the same set of edge weights appear in the two MST’s. Is this a coincidence? We’ll see later.) 1 8 7 9 6 9 5 8 8 7 10 9 6 10 9 8 7 9 5 8 4 10 6 2 9 g 4 d f 2 1 2 5 4 8 1 2 2 2 a

Cost = 33 Cost = 22 Cost = 22 a b c e g f d b c e g f d a b c e Fig. 31: Spanning trees (the middle and right are minimum spanning trees. Steiner Minimum Trees: Minimum spanning trees are actually mentioned in the U.S. legal code. The reason is that AT&T was a government supported monopoly at one time, and was responsible f or handling all telephone connections. If a company wanted to connect a collection of installations by an private internal phone system, Lecture Notes 42 CMSC 451 AT&T was required (by law) to connect them in the minimum cost manner, which is clearly a spanning tree . . . or is it? Some companies discovered that they could actually reduce their connection costs by opening a new bogus installation. Such an installation served no purpose other than to act as an int ermediate point for connections. An example is shown in Fig. 32. On the left, consider four installations that li e at the corners of a 1 1 square. Assume that all edge lengths are just Euclidean distances. It is easy to see tha t the cost of any MST for this configuration is 3 (as shown on the left). However, if you introduce a new insta llation at the center, whose distance to each of the other four points is 1= p 2. It is now possible to connect these five points with a total cost of 4= p 2 = 2 p 2 2:83. This is better than the MST. Cost = 3 1 Steiner point MST SMT Cost = 2 sqrt(2) = 2.83 Fig. 32: Steiner Minimum tree. In general, the problem of determining the lowest cost interconnection tree betw een a given set of nodes, assuming that you are allowed additional nodes (called Steiner points) is called the Stei ner minimum tree (or SMT for short). An interesting fact is that although there is a simple greedy algori thm for MST’s (as we will see below), the SMT problem is much harder, and in fact is NP-hard. (Luckily for AT& T, the US Legal code is

any edge that crosses a respecting cut is a possible candidate. Recall that a greedy algorithm is one that builds a solution by r epeated selecting the cheapest (or generally locally optimal choice) among all options at each stage.E) be a connected. Note that if A is viable it cannot contain a cycle. There exists a unique path between any two vertices of a free tree. We say that a subset A E is viable if A is a subset of edges in some MST. V − S) is just a partition of the vert ices into two disjoint subsets. and we will add edges one at a time.rather ambiguous on the point as to whether the phone company was required to us e MST’s or SMT’s in making connections. let us review some basic facts about free trees. which will initially be empty. The intuition behind the greedy MST algorithms is s imple.) MST Lemma: Let G = (V. They are all quite easy to prove. A generic greedy algorithm operates by repeatedly adding any safe edge to the current spanning tree. so that it can be applied to both algorithms. (We cannot sa y “the” MST. connected graph whose edges have numeric edge we ights (which may be positive. we maintain a subset of edges A. (It is st ated in complete generality. An edge (u. since it is not necessarily unique. In other words. and we wish to know which ed ges can be added that do not induce a cycle in the current MST. undirected graph with real-valued weigh . An edge of E is a light edge crossing a cut. It essentially says that we can always augment A by adding the minimum weight edge that crosses a cut which respects A. Lemma: A free tree with n vertices has exactly n − 1 edges. Before presenting these algorithms. An important characteristic of greedy algorithms is that once they make a choice. the choice (u.) Generic approach: We will present two greedy algorithms (Kruskal’s and Prim’s algori thms) for computing a minimum spanning tree. Adding any edge to a free tree creates a unique cycle. unt il A equals the MST. Let G = (V. if among all edges crossing the cut . v) crosses the cut if one endpoint is in S and the other is in V − S. (Note that viability is a property of subsets of edges and safety is a property of a single edge. If we have computed a partial MST. they never “unmake” this choice. it has the minimum weight (the light edge may not be unique if there are duplicate edge weights).E) be an undirected. The main theorem which drives both algorithms is the following.) When is an edge safe? We consider the theoretical issues behind determining whet her an edge is safe or not. then the lightest edge crossi ng a cut is a natural choice. Let S be a subset of the vertices S V . we Lecture Notes 43 CMSC 451 say that a cut respects A if no edge in A crosses the cut. v) is a safe choice to add so that A can still be extended to form an MST. Intuitio n says that since all the edges that cross a respecting cut do not induce a cycle. Breaking any edge on thi s cycle restores a free tree. v)g is viable. negative or zero).) We say that an edge (u. It is not hard to see why respecting cuts are important to this problem. A cut (S. v) 2 E − A is safe if A [ f(u. Given a subset of edges A.

y) is not in A (because the cut respects A). 8 7 4 9 4 4 x x x T + (u. v) is lightest edge crossing the cut. and (u. let (S.y) + (u. until we have a single tree containing all the vertices. Let T be any MST for G (see Fig. then it is added to A. v) is safe for A. and since any cycle must cross the cut an even number of times.e. and we consider the next edge in o rder. v) < w(x. The edge (x. thus creating a cycle. v) then we are done. v) to T. the edges of A will induce a forest on the vertices. Let A be a viable subset of E (i. V − A0). Consider the cut (A0. Thus w(T0) < w(T). Observe that this strategy leads to a correct algorithm. As the algorithm cont inues. If T contains (u. Let A0 denote the tree of the forest A that contains vertex u. a subset of some MST). (u. Edge (u.v) 8 u y 6 v y u v u v y A Fig. v) be a light edge crossing this cut. V − S) be any cut t hat respects A. By removing (x. v) is the light edge across the cut (because any lighter edge would have been considered earlier by the algorithm). call it T0. Proof: It will simplify the proof to assume that all the edge weights are distin ct. Every edge crossing the c ut is not in A. v). y) +w(u. v) is safe. Lecture Notes 44 CMSC 451 The only tricky part of the algorithm is how to detect efficiently whether the a . If it does. Then the edge (u. We will derive a contradiction. and so this cut respects A. We have w(T 0) = w(T)−w(x. v) that Kruskal’s algorithm seeks to add next. Since u and v are on opposite s ides of the cut. v): Since (u. V − S). If the next edge does not induce a cycle among the curre nt set of edges.ts on the edges. Add the edge (u. y). ). there must be at least one other edge (x. y) we restore a spanning tree. Why? Consider the edge (u.v) T’ = T − (x. 33: Proof of the MST Lemma. Note that as this algorithm runs. Thus. and let (u. then this edge is passed over. and suppose that this edge does not induce a cycle in A. we have w(u. the trees of this forest are merged together. v) is the light edge crossing cut (S. This contradicts the assumption that T was an MST. Kruskal’s Algorithm: Kruskal’s algorithm works by attempting to add edges to the A i n increasing order of weight (lightest edges first). Suppose that no MST contains (u. by the MST Lemma. y) in T that crosses the cut.

T he algorithm is shown below. and an example is shown in Fig. v) } } return A } 2 6 5 9 9 7 10 8 2 10 4 8 9 8 7 9 5 6 2 2 1 2 4 . on a set of size n. The set A can be stored as a simple list of edges. but th is will take too much time. v): Merge the set containing u and the set containing v into a common s et.) In Kruskal’s algorithm. Kruskal’s Algorithm Kruskal(G=(V. We want a fast test that tells us whether u and v are in the same tree of A.w) { A = {} // initially A is empty for each (u in V) Create_Set(u) // create set for each vertex Sort E in increasing order by weight w for each ((u. This can be done by a data structure (which we have not studied) called the disj oint set Union-Find data structure. and the sets will be vertices in each tree of A. (The Union-Find data structure is quite inter esting. For our purposes it suffices to know that each of these ope rations can be performed in O(log n) time.E).v) to A Union(u.v) from the sorted list) { if (Find_Set(u) != Find_Set(v)) { // u and v in different trees Add (u. You are not responsible for knowing how this data structure works (which is desc ribed in CLRS). However we will not go into this here. O(log n) time is fast enough for its use in Kruskal’s algorithm. the vertices of the graph will be the elements to be store d in the sets. Find-Set(u): Find the set that contains a given item u. You may use it as a “black-box”. Union(u. This data structure supports three operations: Create-Set(u): Create a set containing a single item v.ddition of an edge will create a cycle in A. because it can actually perform a sequence of n operations much faster than O(n log n) time. We could perform a DFS on subgraph induced by the edges of A. 34.

5 5 2 1 1 2 2 1 2 a 4 8 4 9 7 6 10 9 8 7 6 10 9 9 8 8 10 7 6 8 9 9 2 4 8 9 8 10 7 9 5 6 10 8 9 8 7 9 5 6 a b c e d g a b c e g a c e a b c c c c c 1 4 .

and each iteration involves a constant number of accesses to the Union-Find data structure on a collection of V items. we could write this more simply as (E log V ). The for-loop is iterated E times. (Whatever that means!) Different ways to grow a tree: Kruskal’s algorithm worked by ordering the edges. Thus the total running time is the sum of these. Thus. let V be the number of vertices and E be the number of edges. Analysis: How long does Kruskal’s algorithm take? As usual. In contrast. Since V is asymptotically no larger than E. Its run ning time is essentially the same as Kruskal’s algorithm. There are two reasons for studying Prim’s algorithm. Intuitively Krus kal’s works by merging or splicing two trees together. not only is Prim’s a different way to solve the same MST problem. Observe that it t akes (E logE) time to Lecture Notes 45 CMSC 451 sort the edges. Thus each access is (V ) ti me. We start with a root vertex r (it can be any vertex). taking care never to introduce a cycle. until all the vertices are in the same tree. 34: Kruskal’s Algorithm. that we will study for a completely different problem. The first is to show that there is more than one way to solve a problem (an important lesson to learn in algorithm design). It differs from Kruskal’s algorithm only in how it selects the next safe edge to add at each step. Baruvka’s algorithm is not described in CLRS. which is ((V +E) log V ). for a total of (E log V ). At any time. a nd inserting them one by one into the spanning tree. Each vertex is labeled according to the set that con tains it.8 2 1 2 a c c c c c c c e c c c c c c 2 2 5 4 1 a c c c c Fig. the subset of edges A forms . Prim’s algorithm builds the tree up by adding leaves one at a time to the current tree. Lecture 13: Prim’s and Baruvka’s Algorithms for MSTs Read: Chapt 23 in CLRS. it is also the same way to solve a different problem . shortest paths. called Dijkstra’s algorithm. we may assume that E V − 1. O((V + E) log V ). Since the graph is connected. and the second is that Prim’s algorithm looks very much like another greedy algorithm. Prim’s Algorithm: Prim’s algorithm is another greedy algorithm for minimum spanning trees.

where n is the number of items in the heap. The priority queue suppor ts three operations. The pro blem is that when a vertex is moved from one side of the cut to the other. A priority queue can be implemented using the same heap data structure used in h eapsort. It is easy to see. new key): Decrease the value of u’s key value to new key. and others that were not crossing the cut are.a single tree (in Kruskal’s it formed a forest). this results in a complicated seque nce of updates. we wil l make use of a priority queue data structure. r u 10 10 u 12 11 4 5 7 6 r 3 5 7 6 12 9 Fig. The proc ess is illustrated in the following figure. and how to determine the light edge quickly. Then u is added to the vertices of S. Recall that this is the data structure used in HeapSort. an d its complement (V −S). We also store in pred[u] t he end vertex of this edge in S. To do this. since this is what we are removing with each step of the algorithm. that the key questions in the efficient implementation of Pri m’s algorithm is how to update the cut efficiently. Observe that if we consider the set of vertices S currently part of the tree. There is a much more elegant solution. and the cut changes. What do we store in the priority queue? At first you might think that we should store the edges that cross the cut. In the figure. Which edge should we add next? The MST Lemma from the previous lecture tells us that it is safe to add the light ed ge. This is a data structure that stores a set of items. We look to add a single vertex as a leaf to the tree. For each vertex in u 2 V − S (not part of the current spanning tree) we associate u with a key value key[u]. insert(u. 35: Prim’s Algorithm. . extractMin(): Extract the item with the minimum key value in Q. where each item is associated with a key value. this is the edge of weight 4 going to vertex u. Lecture Notes 46 CMSC 451 decreaseKey(u. All of the above operations can be performed in O(log n) time. Note that some edges that crossed the cut before are no longer crossing it. and this is what makes Prim’s algorithm so nice. which is the weight of the lightest edge going from u to any vertex in S. we have a cut of the graph and the current set of tree edges A respects this cut. key): Insert u with the key value key in Q.

For each incide nt edge. Thus the time is O( log V + deg(u) log V ) time. pred[v] = u. // put vertices in Q while (Q. Q = new PriQueue(V). Here is Prim’s algorithm. // new lighter edge out of v Q.v) < key[v])) { key[v] = w(u.r) { for each (u in V) { // initialization key[u] = +infinity. // start at root pred[r] = nil. } } color[u] = black. } [The pred pointers define the MST as an inverted tree rooted at r] } The following figure illustrates Prim’s algorithm. This is exactly the same as Kruskal’s algorithm. Prim’s Algorithm Prim(G. } key[r] = 0. The arrows on edges indicate th e predecessor pointers.nonEmpty()) { // until all vertices in MST u = Q.If there is not edge from u to a vertex in V − S. so this is (E log V ). To analyze Prim’s algorithm. We will also need to know which vertices are in S and which are not. we spend potentially O(log V ) time decreasing the key of the neighboring vertex. Lecture Notes 47 CMSC 451 8 9 2 5 10 2 5 6 . We do this by coloring the vertices i n S black. The root vertex r can be any vertex in V .E) = X u2V (log V + deg(u) log V) = X u2V (1 + deg(u)) log V = log V X u2V (1 + deg(u)) = (log V )(V + 2E) = ((V + E) log V ): Since G is connected. then we set its key value to +1.w. color[u] = white.decreaseKey(v. It takes O(log V ) to extract this vertex from the queue. // vertex with lightest edge for each (v in Adj[u]) { if ((color[v] == white) && (w(u.extractMin().v). V is asymptotically no greater than E. and the numeric label in each vertex is the key value. we account for the time spent on each vertex as it is extracted from the priority queue. So the overall running time is T(V. The other steps of the update are constant time. key[v]).

5 5 2 ? ? .5 Q: 2.2 9 8 7 4 8 9 10 4 8 4 8 9 4 8 9 10 2 5 6 2 9 8 7 7 10 10 2 5 6 2 9 8 4 8 9 10 2 5 6 2 7 2 5 6 2 9 8 7 6 9 2 9 8 7 9 8 4 8 2 1 4 Q: 4.? Q: 1.?.?.? Q: <empty> Q: 2.? Q: 8.?.?.10.8.2.8.10.2.

Initially. Recall that with each stage of Kruskal’s algorithm. As a result. By the above observation. many components will be merged together into a single component. it may seem like complete overkill to consider yet another algorithm.? ? 8 4 8 10 10 2 5 2 ? 2 5 1 ? 2 ? 1 8 1 1 1 1 1 Fig. Baruvka’s algorithm is similar to Kruskal’s algorithm. which add edges one at a time. The reason for studying this algorithm is that of the three algorithms. all of these edges are safe. A fairly high-level description of Baruvka’s algorithm is given below. We then apply DFS to the edges of A. Let us call each subtree a component. So. we argued (from the MST Lemma) that the lightest such edge will be safe to add to the MST. In fact. w) { initialize each vertex to be its own component. Baruvka’s algor ithm adds a whole set of edges all at once to the MST. Baruvka’s Algorithm: We have seen two ways (Kruskal’s and Prim’s algorithms) for solvi ng the MST problem. This suggests a more parallel way to grow the MST. in the sense that it works by maintaining a collection of disconnected trees. This process is repeated until only one component remains. Note that two components might select the same edge by this process. Unlike Kruskal’s and Prim’s algorithms. it is the easiest t o implement on a parallel computer. Baruvka’s Algorithm Baruvka(G=(V. well before the first computers). a closer inspection of the proof reveals that the cheapest edge leaving any component is always safe.E). we add the lightest -weight edge that connects two different components together. A = {}. to identify the new components. each ver tex is by itself in a one-vertex component. 36: Prim’s Algorithm. We say t hat such an edge leaves the component. To prove Kruskal’s algorithm correct. so we may add them all at once to the set A of edge s in the MST. This one i s called Baruvka’s algorithm. // A holds edges of the MST . It is actually the oldest of the three algorithms (invented in 1926. Each component determines the lightest edge that goes from inside the component to outside the component (we don’t care where).

Then we can traverse each component again to determine the lightest edge that leaves the component. return A. we can do all this without having to perform two separate DFS’s. With these labels it i s easy to determine which edges go between components (since their endpoints have different labels).v} to A (unless it is already there). Each DFS tree will correspond to a separat e component. First.do { for (each component C) { find the lightest edge (u. except to note that they can be solved in (V + E) time through DFS.) The algorithm is illustrat ed in the figure below. } while (there are 2 or more components). which we will no t spell out in detail.v) with u in C and v not in C. 8 7 a 6 a h h h h h a h 12 15 2 9 14 3 10 11 4 13 1 h c a h e h c e a 6 7 8 12 15 2 9 14 3 10 . but only traversing the edges of A to compute the components. } apply DFS to graph H=(V. with a little more cleverness.A). // return final MST edges Lecture Notes 48 CMSC 451 There are a number of unspecified details in Baruvka’s algorithm. add {u. We label each vertex with its component number as part of this process. to compute the new components. we may apply DFS . (In fact.

Analysis: How long does Baruvka’s algorithm take? Observe that because each iterat ion involves doing a DFS. Thus. The quest ion is how many iterations are required in general? We claim that there are never more than O(log n) iterat ions needed. To see why. Each of the m components. let m denote the number of components at some stage. each iteration (of the outer do-while loop) can be performed in (V +E) time.11 4 13 1 a 10 e i g h c a 6 7 8 12 15 2 9 14 3 10 11 4 13 1 f h h h h h h h h 6 7 8 12 15 2 9 14 3 11 4 13 1 d b Fig. the number of componen ts decreases by at least . 37: Baruvka’s Algorithm. will me rge with at least one other component. but never higher than m=2 (if they merge in pairs). Afterwards the number of remaining components could be a low as 1 (if they all merge together).

Lecture 14: Dijkstra’s Algorithm for Shortest Paths Read: Chapt 24 in CLRS. It is possible to have graphs with negative edges. We have already seen that breadth-first search is an O(V + E) algorithm for finding shortest paths from a single source vertex to all other vertices. we define the length of a Lecture Notes 49 CMSC 451 path to be the sum of edge weights along the path. Suppose that the graph ha s edge weights.) Single Source Shortest Paths: The single source shortest path problem is as foll ows. Most algorithms for this problem are variants of the single-source algorithm that we will present. We will stress the task of computing the minimum distance from the source to eac h vertex. We are given a directed graph with nonnegative edge weights G = (V. V is asymptotically no larger than E. since G is connected. we will construct the reversal of the shortest path to v. called Dijkstra’s algorithm. but there are other global methods that are faster. Computing the actual path will be a fairly simple extension. ((u. so we can write this more succinctly as (E log V ). v) to be the length of the minimum length path from u to v. (u. s 2 V .half with each iteration. Thus. and we wish to compute the shortest paths from a single source vertex to all other vertices in the graph. u and v. u) = 0 by considering path of 0 edges from u to itself. There is also a single sink problem. and the weights represent the cost of traveling from one city to another (nonexistent edges can be thought of a having infinite cost). this can happen at m ost lg V time. The text discusses the Bellman-F ord algorithm for finding shortest paths assuming negative weight edges but no negative-weight cycles are present. As in breadth-first search. Think of the vertices as cities. Since we start with V components. which assumes there are no n egative edge weights. there are other formulations of the shortest path problem. but in order for the shortest path to be well defined. Shortest Paths: Consider the problem of computing shortest paths in a directed g raph. Shortest Paths and Relaxation: The basic structure of Dijkstra’s algorithm is to m aintain an estimate of the shortest . Computing all-pairs shortest paths can be solved by ite rating a single-source algorithm over all vertices. Again. until only one component remains. we need to add the requirement that there be no cycles whose total cost is negative (otherw ise you make the path infinitely short by cycling forever through such a cycle).E) and a distinguished source vertex. The problem is to determine the distance from the source vertex to every vertex in the graph. which can be solved i n the transpose digraph (that is. Thus all three algorithms have the same asymptotic running time. By following the predecessor pointers b ackwards from any vertex. By the way. assuming that the graph has no edge weights. One may w ant just the shortest path between a single pair of vertices. by reversing the edges). for e ach vertex we will have a pointer pred[v] which points back to the source. When edge weights are present. We will discuss a simple greedy algorithm. the total running time is ((V + E) log V ) time. Define the distance between t wo vertices.

there is always evidence of a path of that length. v) we get a path to v of length d[u]+w(u. v u 8 3 5 s 0 relax(u. Intuitively. so d[v] =1. It is not hard to see that if we perform Relax(u. then push it a little closer to the optimum. They are completely different. v). The cleverness of a ny shortest path algorithm is to perform the updates in a judicious manner. then you ne ed to update d[v]. Suppose that we h ave already computed current estimates on d[u] and d[v]. v) repeatedly over all edges o f the graph. Therefore d[v] (s. v). Relaxing an edge Relax(u. 38: Relaxation. call this d[v]. then take it pred[v] = u // record that we go through u } } Lecture Notes 50 CMSC 451 Observe that whenever we set d[v] to a finite value. which we do b y updating v’s predecessor pointer.path for each vertex. and sees more and more vertices.) Intuitively d[v] will be the length of the shortest path that the algorithm knows of from s to v. As the algorithm goes on. This. Initially.v) { if (d[u] + w(u. In particular. we should update d[v] to the value d[u] + w(u. v). If d[v] = (s. if you can see that your solution is not yet reached an optimum value. 38. By taking this path and following it with the edge (u.v) // yes. if you discover a path from s to v shorter than d[v]. In particular. the d[v] values will eventually converge to the final true distance value from s. Consider an edge from a vertex u to v whose weight is w(u. then further relaxations cannot change its value. If this path is better than the existing path of length d[v] to v. it attempts to update d[v] for each ve rtex in the graph. The process by which an estimate is updated is called relaxation. v).v) < d[v]) { // is the path through u shorter? d[v] = d[u] + w(u. v). This notion is common to many optimization algorithms. We should also remember that the shortest path to v passes through u. Thi s is illustrated in Fig. Initially d[s] = 0 and all the other d[v] values a re set to 1. we know of no paths. until all the d[v] values converge to the true shortest distances. the best . Here is how re laxation works. We know that there is a path from s to u of weight d [u]. value will always greater than or equal to the true shortest path distance from s to v. so the convergence is as fast as p ossible. (NOTE: Don’t confuse d[v] with the d[v] in t he DFS algorithm.v) s v u 11 3 5 0 Fig.

Also recall that if we implement the priority queue usi ng a heap. S V . Notice that the coloring is not really used by the algorithm. Later we will justify why this is the proper choice. To see that Dijkstra’s algorithm correctly gives the final true distances. we store the vertices of V − S in a priority queue (e. for each vertex i n u 2 V − S. To implement this. Initially S = . and Decrease Key(). it is possi ble to infer that result of the relaxation yields the final distance value. the empty set. Lemma: When a vertex u is added to S. Here is Dijkstra’s algorithm. has a cross reference l ink to the priority queue entry). Dijkstra’s Algorithm: Dijkstra’s algorithm is based on the notion of performing repe ated relaxations. Initially all vert ices are white. Each vertex “knows” its location in the priority queue (e. where the key value of each vertex u is d[u]. namely (E log V ).g. whenever a relaxation is being performed. This is a consequence of the following lemma. Proof: It will simplify the proof conceptually if we assume that all the edge we . How do we select which vertex among the vertices of V − S to add next to S? Here i s where greedy selection comes in. the running time is the same. that is d[v] = (s. Note the similarity with Prim’s algo rithm. and we set d[s] = 0 and al l others to +1. Since at the end of the algorithm. and each entry in the priority queue “knows” which vertex it represents. v).possible would be to order relaxation operations in such a way that each edge is relaxed exactly once. Dijkstra’s algorithm does exactly this. and we set color[v] = black to indicate that v 2 S. Correctness: Recall that d[v] is the distance value assigned to vertex v by Dijk stra’s algorithm. One by one we select vertices from V − S to add to S. we need to show that d[v] = (s. although a different key value is used there. It is impor tant when implementing the priority queue that this cross reference information is updated. The set S can be implemented using an array of vertex colors.e. a heap). Dijkstra recognized that the best way in which to perform relaxations is by increasing order of distance from the source. for which we claim we “know” the true distance. and let (s. Dijkstra’s algorithm operates by maintaining a subset of vertices. then all distance estimates are correct. 39. Extract Min(). that is. we maintain a distance estimate d[u]. but it has been in cluded to make the connection with the correctness proof a little clearer. which states that once a vertex u has been added to S (i. take the unprocessed vertex that is closest (by our estimate) to s.) An example is presented in Fig. on a priority queue of s ize n each in O(log n) time. This way. The greedy thing to do is to take the vertex of V − S for which d[u] is minimum.. (Note the remarkable similarity to Prim’s algorithm.g. Because of the similarity between this a nd Prim’s algorithm. d[u] is the true shortest distance from s to u. v) denote the length of the true shortest path from s to v. col ored black). we can perform the operations Insert(). In order to perform this selection efficiently. v) when the algorithm terminates. d[u] = (s. all vertices a re in S. u).

By our observations about relaxation. Consider the situation just prior to the insertion of u.v) d[v] = d[u] + w(u. u).decreaseKey(v. d[u] is never less th an (s.s) { for each (u in V) { // initialization d[u] = +infinity color[u] = white pred[u] = null } d[s] = 0 // dist to source is 0 Q = new PriQueue(V) // put all vertices in Q while (Q. Because s 2 S and u 2 V − S. (Note that it may be that x = s and/or y = u).v) < d[v]) { // Relax(u.v) Q. where x 2 S and y 2 V − S. at some point this path must first jump out o f S. y) be the edge taken by the path.ights are strictly positive (the general case of nonnegative edges is presented in the text). u).w. Let (x. u). d[v]) pred[v] = u } } color[u] = black } [The pred pointers define an ‘‘inverted’’ shortest path tree] } s 3 2 6 5 2 8 5 1 7 6 7 2 1 8 4 5 5 2 3 s 3 5 s 7 2 1 8 4 .extractMin() // select u closest to s for each (v in Adj[u]) { if (d[u] + w(u. Lecture Notes 51 CMSC 451 Dijkstra’s Algorithm Dijkstra(G. Consider the true shortest path from s to u. thus we have d[u] > (s. Suppose to the contrary that at some point Dijkstra’s algorithm first attempts to add a vertex u to S for which d[u] 6= (s.nonEmpty()) { // until all vertices processed u = Q.

39: Dijkstra’s Algorithm example.5 2 3 s 7 2 1 8 4 5 5 2 3 s 2 2 0 5 2 7 4 2 8 0 2 5 6 7 ? 10 ? ? ? ? ? 7 7 2 1 8 4 5 5 6 0 0 7 2 0 5 7 5 0 2 7 0 5 2 3 s 7 1 4 5 5 2 Fig. pred[u] s to u? shorter path from d[y] > d[u] y .

We will allow G to have negative cost edges. rather than the more common adjacency list. intuitively means that there is no direct l ink between these two nodes. The reason for setting wii = 0 is that there is always a trivial path of length 0 . All-Pairs Shortest Paths: We consider the generalization of the shortest path pr oblem. v). we would have set d[y] = d[x] + w(x. If (u. u).E) be a directed graph with edge weigh ts. We will present a (n3) algorithm.2 in CLRS. The distance between two vertices (u. and w as we usually do. +1 if i 6= j and (i. 40: Correctness of Dijkstra’s Algorithm. v. is an edge of G. u) < d[u]: Thus y would have been added to S before u. we will assume that the digraph is represented as an adjacen cy matrix. j) if i 6= j and (i. Recall that the cost of a path is the sum of edge weights along the path. Why? Since x 2 S we have d[x] = (s. v) is the cost of the minim um cost path between them. storing all the inter-vertex distances will require (n2) storage. and thus d[y] = (s. wij = 8< : 0 if i = j. using i.) Since we applied relaxa tion to x when it was added. so the savings is not justified here. y). but we will not allow G to have any negative cost cycles. x). and by hy pothesis. Now observe that since y appears somewhere along the shortest path from s to u ( but not at u) and all subsequent edges following y are of positive weight. y) = (s. Lecture Notes 52 CMSC 451 We argue that y 6= u. d[u] is not correct. then the weight of this edge is denoted w(u. w(i. we have (s. j) 2 E. (Since u was the fi rst vertex added to S which violated this. and hence the direct cost is infinite. We let wij denote the entry in row i and column j of w. which are based on t he edge weights in the digraph. to computing shortest paths between all pairs of vertices. j) =2 E. y) < (s. Setting wij = 1 if there is no edge. Thus d[y] is correct. all prior vertices satisfy this. we will employ common matrix notation. Because the algorithm is matrix-based. Although adjacency lists are generally more efficient for sparse graphs.x S s u Fig. y) < (s. Let G = (V. so they cannot be the same. For this algorithm. j and k to denote vertices rather than u. We consider the problem of determining the cost of the shortest path between all pairs of vertices in a weighted directed graph. Input Format: The input is an n n matrix w of edge weights. called the Floyd-Warshall algor ithm. in contradiction to our assumption t hat u is the next vertex to be added to S. v) E. This algorithm is based on dynamic programming. Lecture 15: All-Pairs Shortest Paths Read: Section 25.

v2. Formulation: Define d(k) ij to be the shortest path from i to j such that any intermediate vertices on th e path are chosen from the set f1. 2. Recovering the shortest paths will also be an issue. j). Floyd realized that the same technique could be used to compute shortest paths w ith only minor variations. whether u can reach v. kg. Lecture Notes 53 CMSC 451 Floyd-Warshall Algorithm: The Floyd-Warshall algorithm dates back to the early 6 0’s. but these intermediate can only be chosen f rom among f1. notice how the value of d(k) 5. If the shortest path travels directly from i to j without passing through any ot her vertices. A natural way of doing this is by limiting the number of edges of the path. they instead limit the set of vertices through which the path is allowed to pass. F or example. we consider a path from i to j which either consists of the sing le edge (i. the key is reducing a large problem to smaller problem s. : : : . The value of mid[i. To help us do this. Note that a path consisting of a single edge has no intermediate vertices. j]. It cannot be negative. v −1 are the intermediate vertices of thi s path. in order to reconstruct the final shortest path in (n) time. 2.1. : : : . kg. then mid[i. As with any DP algorithm. Rather than limiting the number of edges on the path. j] will be set to null. in the digraph shown in the Fig. and if it is positive. there is no point in using it as part of any shortest pat h. but it turns out that this does not lead to the fastest algorithm (but is an approach worthy of consideration). (Note that in digraphs it is possibl e to have self-loop edges. The Floyd-Warshall algorithm runs in (n3) time. Warshall was interested in the weaker question of reachability: determine for each pair of vertices u an d v. j). i) may generally be nonzero. 41(a). In particul ar. v3. v i we say that the vertices v2. : : : . The main feature of the Floyd-Warshall alg orithm is in finding a the best formulation for the shortest path subproblem. j] will be a vertex that is somewhere alon g the shortest path from i to j. The path is free to visit any subset of these vertices.(using no edges) from any vertex to itself. w e will also compute an auxiliary matrix mid[i. In other words. : : : . These intermediate values behave somewhat like the predecessor poin ters in Dijkstra’s algorithm. 9 4 6 3 1 4 1 1 (a) (b) (5. and to do so in any order. for a path p = hv1. the shortes t path cost from vertex i to j.6)     . and so w(i. or it visits some intermediate vertices along the way.) The output will be an n n distance matrix D = dij where dij = (i.6 changes as k varies. since we assume that th ere are no negative cost cycles.

6) d d d d d = 6 = 8 = 9 = 13 5. kg: Don’t go through k at all: Then the shortest path from i to j uses only intermedia te vertices f1. and the shortest path from k to j. 6i has the lowest cost of 8. Do go through k: First observe that a shortest path does not pass through the sa me vertex twice. so we can assume that we pass through k exactly once.6) (5. : : : . 41: Limiting intermediate vertices. 3.) That is. : : : . (The assumption that there are no ne gative cost cycles is being used here. assuming that the intermediate vertices are chosen from f1..k−1 5 4 2 6 3 (4) Fig. k − 1g and hence the length of the shortest path is d(k−1) ij . For example d(3) 5.6 = INF (0) (k−1) 1 dij (k−1) dik (k−1) dkj i k j Vertices 1. : : : .6 (2) 5. Since of these paths uses intermediate vertices only in f1.2. Floyd-Warshall Update Rule: How do we compute d(k) ij assuming that we have already computed the previous matrix d(k−1)? There are two basic cases.6 (no path) (5. and then from k to j.1.6) (5. 3g.2.6 (1) 5.5. we go from i to k. k −1g.. 2..6 can go through any combination of the intermediate vertices f1. depending on the ways that we might get from ve rtex i to vertex j.4. . 2. the length of the path is d(k−1) ik + d(k−1) kj . 2.2. of which h5..3. 2. In order for the overall path to be as short as possible we should take the shortest path from i to k.6 (3) 5.

up through section 34. mid[i .n. The space used by the algorithm is (n2 ).k] + d[k.. they occur i n row k and column k..2. which is illustrated in Fig.n]) { array d[1. but this will be prohibitively slow because the same value may be reevaluat ed many times. Floyd-Warshall Algorithm Floyd_Warshall(int n. Here is the complete algorithm.j]) { d[i. Complexity Theory: At this point of the semester we have been building up your “ba g of tricks” for solving algorithmic problems. we compute it by storing the values in a table. d(k) ij = min d(k−1) ij .n.. 1. and looking the values up as we need them. Hopefully when presented with a problem you now have a little better i ..j] = null } } for k = 1 to n do // use intermediates {1. Consider which entries might be overwritten and then reused.to j if (d[i.j] mid[i.. d(k−1) ik + d(k−1) kj for k 1: The final answer is d(n) ij because this allows all possible vertices as intermediate vertices. int w[1. We could write a recursive program to compute d(k) ij .) Lecture 16: NP-Completeness: Languages and NP Read: Chapt 34 in CLRS.k} for i = 1 to n do // . We have also included mid-vertex pointers. We will leave the extraction of the shortest path as an exercise .n] for i = 1 to n do { // initialize for j = 1 to n do { d[i.j] = d[i.k] + d[k.. (Hint: The danger is that values may be overwritte n and then used later in the same phase. 42. Instead.. It can be shown that the overwritten values are equal to their original values.Lecture Notes 54 CMSC 451 This suggests the following recursive rule (the DP formulation) for computing d( k). Clearly the algorithm’s running time is (n3).j]) < d[i.j] = k // new path is through k } return d // matrix of distances } An example of the algorithm’s execution is shown in Fig. 41(b). It is left as an exer cise that this does not affect the correctness of the algorithm. 1.. j] for extracting the final shortest paths..j] // new shorter path length mid[i. d(0) ij = wij .from i for j = 1 to n do // .j] = W[i. Observe that we deleted all references to the superscript (k) in the code.

greedy. All of this is fine if it helps you discover an acceptably efficient algorithm t o solve your problem. DFS. what sort of data structures might be relevant (trees. What sort of design paradigm should be used (divide-and-con quer. grap hs) and what representations would be best (adjacency list. Although Lecture Notes 55 CMSC 451 5 9 3 1 12 9 1 2 1 7 1 6 5 2 5 9 12 6 5 9 12 1 (3) d = (1) d = (4) 1 4 8 4 2 1 8 2 4 8 4 1 3 4 5 d = 4 3 2 0 3 4 1 5 0 1 6 4 7 0 5 7 2 3 0 0 8 ? 1 ? 0 1 ? 4 ? 0 ? ? 2 9 0 ? 0 1 ? 0 8 ? 1 4 12 0 5 ? 2 9 0 0 8 9 1 4 12 0 5 7 2 3 0 ? 0 1 ? . dynamic programming).dea of how to go about solving the problem. heaps. an d nothing seems to work. adjacency matrices). The question that often arises in practice is that you have tried every trick in the book. what is the running time of your algorithm.

perhaps n p n.g. or n!. People began to wonder whether there was some unknown paradigm that w ould lead to a solution to these problems. This discovery gave rise to the notion of NP-completeness. or 2(2n). Lecture Notes 56 CMSC 451 your algorithm can solve small problems reasonably efficiently (e. and created possibly the biggest open problems in computer science: is P = NP? We will be studying this concept o ver the next few lectures. Near the end of the 60’s a remarkable discovery was made. but there was also a growing list of problems for which there seemed to be no kn own efficient algorithmic solutions. When you analyze its running time. or worse! Near the end of the 60’s where there was great success in finding efficient soluti ons to many combinatorial problems. n = 1. . n 20) the r eally large applications that you want to solve (e. 42: Floyd-Warshall Example.000) your algorithm never terminates .g. Many of these hard probl ems were interrelated in the sense that if you could solve any one of them in polynomial time.000 or n = 10.4 12 0 5 ? 2 3 0 7 3 4 7 1 1 2 3 8 5 ? = infinity 5 0 1 6 0 8 9 1 1 1 4 3 2 1 4 2 3 1 4 3 2 1 4 3 2 d = (2) (0) d = Fig. you realize that it is running in exponential time. then yo u could solve all of them in polynomial time. or perhaps some proof that these problems are inherently hard to solve and no algorithmic solutions exist that run under exponential time. or 2n. Newly updates entries are circled.

You could describe graphs in some highly inefficien t way. such as by listing all of its cycles. the size of the input. we assume that there is not some significantly shorter way of providin g the same information. Instead we will be trying to show that a problem cannot be solved efficiently. We will assume that numbers are expressed in binary or some higher base and graphs are expressed using either adjacency matrices or adjacenc y lists. We have measured the running time of algorithms using worst-case complexity. so the user is allowed to choose k = n. The goal is no longer to prove that a problem can be solved efficiently by presenting an alg orithm for it. We have also assumed that operations on numbers can be performed in constant time. We have made use of the fact that an intelligent programmer could fill in any missing de tails. we should be more careful and assume that arithmetic operations require at least as much time as there are bits of precision in the numbers being stored. When designing algorithms it has been possible for us to be rather informal with various concepts. since we do not want leave any “loopholes” that would allow someone to subvert the rules in an unreasonab le way and claim to have an efficient solution when one does not really exist. . From now on. A problem is said to be solvable in polynomial time if there is a polynomial time algorithm that solves it. n. The question is how to do this? Laying down the rules: We need some way to separate the class of efficiently sol vable problems from inefficiently solvable problems. as a function of n. We have defined input size variously for different problems. For example. A polynomial time algorit hm is any algorithm that runs in time O(nk) where k is some constant that is independent of n. suppose you have an algorithm which inputs a graph of size n and an integer k and runs in O(nk) time . Some functions that do “look” like polynomials are not. We will do this by considering problems that can be solved in polynomial time. Up until now all the algorithms we have seen have had the property that their wo rst-case running times are bounded above by some polynomial in the input size. Is this a polynomial? No. because k is an input to the problem. im plying that the running time would be O(nn) which is not a polynomial in n. but this would also be unacceptable. Some functions that do not “look” like polynomials (such as O(n log n)) are bounded above by polynomials (such as O(n2)). For example .This area is a radical departure from what we have been doing because the emphas is will change. so that it is clear that arithmetic can be performed efficiently. We will usually restrict numeric inputs to be integers (as opposed to calling th em “reals”). By a reasonably efficient encoding. the task of proving that something cannot be done efficiently must be handled much more care fully. but that would be unacceptably inefficient. but the bottom line is the number of bits (or bytes) that it takes to represent the input using any reasonably efficient e ncoding. However. you could write numbers in unary notation 111111111 = 1002 = 8 rather t han binary. The important thing is that the e xponent must be a constant independent of n.

and “no” otherwise. does G have a spanning tree whose weight is at most k? This may seem like a less interesting formulation of the problem. At first it may seem strange express ing a graph as a string. the adjacency mat rix encoded as a string) followed by an integer k encoded as a binary number. An algorithm whose running time is O(n1000) is certainly pretty inefficient. Language Recognition Problems: Observe that a decision problem can also be thoug ht of as a language recognition problem. A problem is called a decision problem if its output is a simple “yes” or “no” (or you may think o f this as True/False. we can determine membe rship easily in polynomial time. 2n). this corresponds to the set of all decisions problems that can be solved in polynomial time. We will phrase many optimization problems in terms of decision problems. For rather technical reasons. However. and it does not even ask for the edges of the spanning tree that achieves this weight. and otherwise we reject. the minimum spanning tree decision problem might be: Given a weighted graph G and an integer k. run Kruskal’s algorithm. For example. P is defin ed in terms of how hard it is computationally to recognized membership in the language. If w e show that the simple decision problem cannot be solved efficiently. find the minimum weight triangulation. most NP-complete problems that we will discuss will be phrased as decis ion problems. A set of languages tha t is defined in terms of how .) Note that languages are sets of strings. but obviously anything that is represented in a computer is broken down somehow into a string of bits. then it is certainly not efficient. In the first case we sa y that the algorithm “accepts” the input and otherwise it “rejects” the input. We just store the graph internally. our job will be to show that certain problems cannot be solved efficiently. saying that all polynomial time algorithms are “efficient” is untrue. Given any language.Of course. Lecture Notes 57 CMSC 451 Decision Problems: Many of the problems that we have discussed involve optimizat ion of one form or another: find the shortest path. k). the algorithm would answer “yes” if (G. in the case of the MST language L. then the more general optimization problem certainly cannot be solved efficiently either. If so we accept. and P is a set of languages. When presented with an input string (G. if an algorithm r uns in worse than polynomial time (e. It does not as k for the weight of the minimum spanning tree. For exa mple. Nonetheless. We could define a language L L = f(G. Definition: Define P to be the set of all languages for which membership can be tested in polynomial time. and see whether the final optimal weight is at most k. 0/1. find the minimum cost spanning tree. except for very small values of n . accept/reject). (Intuitively. we can ask the question of how hard it is to determine wheth er a given string is in the language.g.g. k) j G has a MST of weight at most kg: This set consists of pairs. k) 2 L implying that G has a spanning tree of weight at most k. the first element is a graph (e.

let us say a bit about what the general classes look like at an intuitive level. In fact.) This class contains P as a subset. That is. Here is a harder one. (We will give a definition of this below. if not then you may spend a lot of time searching (espec ially if k is large. we will show thatM is NP-complete. but may be discussed in an advanced course on complexity theory. we will be introducing a number of classes. (Although this may be an exagg eration in many cases. it contains a number of easy problems. The other is QBF. but it also contains a number of problems that are believed to be very hard to solve. to say that problem is NP-hard does not mean that it is hard to solve. Rather it means that if we could solve this problem in polynomial time. NPC = NP\NP-hard. We say might because we do not know whether all of these complexity classes are dis tinct or whether they are all solvable in polynomial time. Since we can co mpute minimum spanning trees in polynomial time. until finding one of length at least k. but for our purposes they mean the same things. We will jump back a nd forth between the terms “language” and “decision problems”. We will generally refer to these problems as being “easy” or “efficiently solvable”. then we could s olve all NP problems in polynomial time.) Lecture Notes 58 CMSC 451 NP: This is the set of all decision problems that can be verified in polynomial time. But it is b it more intuitive to explain the concept from the perspective of verification. Originally the term meant “nondeterministic polynomial time”. Thus. Befo re giving all the technical definitions. and no such path exists). which s tands for Quantified Boolean Formulas. it is widely believed that no NP-hard problem is solvable in polynomial time. NP. NP-hard. The te rm NP does not mean “not polynomial”. . we have L 2 P. it does not have to be i n the class NP. The figure below illustrates one way that the sets P. NP-complete: A problem is NP-complete if (1) it is in NP. like n − 1. though.hard it is to determine membership is called a complexity class. If you find one then you can accept and terminate. One is Graph Isomorphism. However. Note that for a problem to be NP hard. It is known that this problem is in NP. M = f(G. NP-hard: In spite of its name. This problem is beyond the scope of this c ourse. and (2) it is NP-hard. which asks whether two graphs are identical up to a renaming of the ir vertices. and NP-comple te (NPC) might look. In what follows. Since it is widely believed that all NP problems are not solvable in polynomial time. So isM 2 P? No one knows the answer. k) j G has a simple path of length at least kg: Given a graph G and integer k how would you “recognize” whether it is in the languag e M? You might try searching the graph for a simple paths. but it is not known to be in P. P: This is the set of all decision problems that can be solved in polynomial tim e. In this problem you are given a boolean formula with quantifiers (9 an d 8) and you want to know whether the formula is true or false. There are some problems in the figure that we will not discuss.

where (G) denotes an encoding of a graph G as a string. it is important to introduce the notion of a verification algorithm. They would simply say “the cycle is hv3. given a language L. and there is no known polynomial time algorithm for this problem. a verification algorithm is an algorithm which given x and a string y called the certificate. does G have a cycle that visits every vertex exactly once.) We can describe this problem as a language recognition problem. This is some piece of information which allows us to verify that a given string is in a language. and given x 2 L. and check that this is indeed a legal cycle and that it visits all the ve rtices of the graph exactly once.NP P NP−Hard One way that things ‘might’ be. 43: The (possible) structure of P. The given cycle is called a certificate. 44: Hamiltonian cycle. Then it would be a v ery easy matter for someone to convince us of this. consider the following languages: UHC = f(G) j G has a unique Hamiltonian cycleg HC = f(G) j G has no Hamiltonian cycleg: Suppose that a graph G is in the language UHC. but they have the property that it is easy to verify whether a string is in the language. NP. Hamiltonian Cycle Graph Isomorphism? MST Strong connectivity Satisfiability Knapsack QBF NPC No Ham. Many language recognition p roblems that may be very hard to solve. there is a very efficient way to verify that a given graph is in HC. However. Note that not all languages have the property that they are easy to verify. What information would someone gi . and there is also a version which asks whether there is a path that visits all vertices. For ex ample. The Hamiltonian cycle pr oblem seems to be much harder. v 13i”. (There is a similar problem on directed graphs. Consider the following problem. : : : . We could then inspect the Lecture Notes 59 CMSC 451 Nonhamiltonian Hamiltonian Fig. suppose that a graph did have a Hamiltonian cycle. v1. v7. Cycle Easy Harder Fig. called the Hamiltonian cycle problem. one which is Hamiltonian and one which is not. the figure below shows two graphs. More formally. Thus. even though we know of no efficient way to solve the Hamiltonian cycle problem. If x is not in L then there is nothing to verify. graph. Polynomial Time Verification and Certificates: Before talking about the class of NP-complete problems. Given an u ndirected graph G. where the language is HC = f(G) j G has a Hamiltonian cycleg. can verify that x is in the language L us ing this certificate as help. For example. and related complexity classes.

In other words. NP-com plete problems are expressed as decision problems. It seems unreasonable to think that this should be so. the following concepts are important. Next ti me we will define the notions of NP-hard and NP-complete. To conv . and we could verify that it is a Hamiltonian cycle. For example MST 2 P but HC is not known (and suspected not) to be in P. suppose that the language is the set of Hamiltonian graphs. assuming that the input has been encoded as a string. O(nk) for some constant k. on the way to defining NP -completeness. and hence can be thought of as language recognition proble ms. It would be covered in a course on complexity theory or formal language theory. but this would not be at all efficient.ve us that would allow us to verify that G is indeed in the language? They could give us an example of the unique Hamiltonian cycle. then we can certainly verify membership in polynomial time. but what sort of certificate could they give us to convince us that this is the only one? They could give another cycle that is NOT Hamiltonian . However it is not known whether P = NP. Thus. NP is a set of languages based on some complexity measure (the complexit y of verification). we can solve it in polynomial time anyway). but this does not mean that there is not another cycle somewhere that is Hamiltonian. but no one has a proof of this. (More formally. Observe that P NP. Summary: Last time we introduced a number of concepts. For ex ample: HC = fG j G has a Hamiltonian cycleg MST = f(G. In other words. The class NP: Definition: Define NP to be the set of all languages that can be verified by a p olynomial time algorithm. We have avoided introducing nondeterminism here . it is hard to imagine that someone could give us some information that would allow us to efficiently c onvince ourselves that a given graph is in the language. This referred to a program running on a nondeterministic computer that can make guesses. and t hen verify that the string is in the language in polynomial time. In particular. if we can solve a problem in polynomial time.4. since there are n! possible cycles in ge neral. such a computer could nondeterministically guess the value of certificate. we do not even need to see a cert ificate to solve the problem. Lecture Notes 60 CMSC 451 Lecture 17: NP-Completeness: Reductions Read: Chapt 34. They could try to list every other cycle of length n. Why is the set called “NP” rather than “VP”? The original term NP stood for “nondeterminis tic polynomial time”. Basically. Certificate: is a piece of evidence that allows us to verify in polynomial time that a string is in a given language. We encode inputs as strings. just being able to verify that you have a correct solution does not help you in finding the actual solution very much. Like P. For example. Most experts believe that P 6= NP. x) j G has a MST of cost at most xg: P: is the class of all decision problems which can be solved in polynomial time. through Section 34. Decision Problems: are problems for which the answer is either yes or no.

(Be sure that you understand this. Thus we have “reduced” problem H to problem U. It is important to note here that thi s supposed subroutine is really a fantasy. The following problem is well-known to be NP-complete. the complexity of U is unknown. thus we are essentially proving that the subroutine cannot exist. Reductions: The class of NP-complete problems consists of a set of decision prob lems (languages) (a subset of the class NP) that no one knows how to solve efficiently. How do we do this? Suppose that we have a subroutine that can solve any instance of problem U in polynomial time. We want to prove that U cannot be solved in polynomial time. we could prove the contrapositive. To establish this. and then derive a contradiction by showing that H c an be solved in polynomial time. However. Suppo se that there are two problems. that is it c annot be solved in polynomial time. We know (or strongly believe) that H cannot be solved in po lynomial time. How would we do this? We want to sho w that (H =2P))(U =2P): To do this. can each of its vertices be labeled with one of 3 different “colors”. NP also seems to have some pretty hard problems to solve. so we have P NP. H and U. It is easy to access the adjacency matrix to determine that this is a legitimate cycle in G. Two countries that share a common border should be colored with differe nt colors. to show that U is not solvable in polynomial time. but we suspect that it too is hard. (U 2 P) ) (H 2 P): In other words. then every problem in NP would be solvable in polyno mial time. We know (or you strongly believe at least) that H is hard. we could supply the certificate consisting of a sequence of vertices along the cycle. Note that since all languages in P can be solved in polynomial time. On the other hand. and hence it is strongly believed that the prob lem cannot be solved in polynomial time. It is well known . Coloring arises in various partitioning problems. Then all we need to do is to show that we can use this subroutine to solve problem H in polynomial time. we will suppo se that there is an algorithm that solves U in polynomial time. this the basis behind all reductions. su ch as HC. The term “coloring” comes from the original applic ation which was in map drawing. let us just consider the following question.ince someone that a graph is in this language. implying that U cannot be solved in polynomial time. they can certainly be verified in polynomial time. NP: is defined to be the class of all languages that can be verified in polynomi al time. where there is a constraint th at two objects cannot be assigned to the same set of the partition. we need to introduce the concept of a reduction. Therefore HC 2 NP. such that no two adjacent vertices have the same label. Lecture Notes 61 CMSC 451 3-coloring (3Col): Given a graph G. but if there were a polyno mial time solution for even a single NP-complete problem. Before discussing reductions.) Example: 3-Colorability and Clique Cover: Let us consider an example to make thi s clearer.

such that S i Vi = V .that planar graphs can be colored with 4 colors. which you will show by proving the contrapositive (CCov 2 P) ) (3Col 2 P): To do this. Clique Cover (CCov): Given a graph G = (V. v) 2 E.E). but after a while of fruitless effort. How can you prove that CCov is likely to not have a polynomial time solution? You know that 3Col is NP-complete. You feel that there is some connection between the CCov problem and the 3Col problem . The only differe nce here is that in one problem the number of cliques is specified as part of the input and in the other the num ber of color classes is fixed at 3. and that each Vi is a clique of G. for two vertices to be in the same color group. V2. In some sense. and this subroutine is a llowed to call the subroutine CCov(G. Thus. they must no t be adjacent. for two vertices to be in the same group they must be adjacent to each other. Lecture Notes 62 CMSC 451 We claim that we can reduce the 3-coloring problem to the clique cover problem a s follows. Give n a graph G = (V. In the figure below we give two graphs. but the requirement adjacent/non-adjacent is e xactly reversed. We put an edge be tween two nodes if they are similar enough to be clustered in the same group. We want to know whether it is possible to cluster all the vertices into k groups. Both problems involve partitioning the vertices up into groups. and there exists a polynomial t ime algorithm for this.E) and an integer k. and hence experts b elieve that 3Col =2 P. That is. output the pair (G. Given a graph G for which we want to determine its 3-colorability. But determining whether 3 colors are possible (even for planar graphs) seems to be h ard and there is no known polynomial time algorithm. k) for any graph G and any integer k. k). this subroutine runs in polynomial time. For our unknown problem U. the problems are almost the same. a nd furthermore. In the clique cover problem. this subroutine returns true if G has a clique cover of size k and false otherwise. you assume that you have access to a subroutine CCov(G. 45: 3-coloring and Clique Cover. Given a graph G and an integer k. one is 3-colo rable and one is not. can we partition the vertex set into k subsets of vertices V1. consider the following problem. 3) where . The clique cover problem arises in applications of clustering. Suppose that you want to solve the CCov problem. The 3Col problem will play the role of the hard problem H. you want to show that (3Col =2 P) ) (CCov =2 P). Vk. How can we use this “alleged” subroutine to solve the wellknown hard 3Col problem? We want to write a polynomial time subroutine for 3Col. 3−colorable Not 3−colorable Clique cover (size = 3) Fig. which we strongly sus pect to not be solvable in polynomial time. v 2 V 0 (u. we say that a subset of vertices V 0 V forms a clique if for every pair of vertices u. In the 3-coloring problem. : : : . the subgraph induced by V 0 is a complete graph. you still cannot find a polynomial time algorithm for the CCov problem.

G denotes the complement of G. (That is, G is a graph on the same vertices, but (u; v) is an edge of G if and o nly if it is not an edge of G.) We can then feed the pair (G; 3) into a subroutine for clique cover. This is illust rated in the figure below. H G _ 3−colorable Coverable by 3 cliques G Not coverable H Not 3−colorable _ Fig. 46: Clique covers in the complement. Claim: A graph G is 3-colorable if and only if its complement G has a clique-cov er of size 3. In other words, G 2 3Col iff (G; 3) 2 CCov: Proof: ()) If G 3-colorable, then let V1; V2; V3 be the three color classes. We claim that this is a clique cover of size 3 for G, since if u and v are distinct vertices in Vi, then fu; vg =2 E( G) (since adjacent vertices cannot have the same color) which implies that fu; vg 2 E(G). Thus every pair of distinct vertices in Vi are adjacent in G. (() Suppose G has a clique cover of size 3, denoted V1; V2; V3. For i 2 f1;2;3g give the vertices of Vi color i. We assert that this is a legal coloring for G, since if distinct vertic es u and v are both in Vi, then fu; vg 2 E(G) (since they are in a common clique), implying that fu; vg =2 E((G) . Hence, two vertices with the same color are not adjacent. Polynomial-time reduction: We now take this intuition of reducing one problem to another through the use of a subroutine call, and place it on more formal footing. Notice that in the example above, we converted an instance of the 3-coloring problem (G) into an equivalent instance of the Clique Cover pr oblem (G; 3). Definition: We say that a language (i.e. decision problem) L1 is polynomial-time reducible to language L2 (written L1 P L2) if there is a polynomial time computable function f, such that for all x, x 2 L1 if and only if f(x) 2 L2. In the previous example we showed that 3Col P CCov: In particular we have f(G) = (G; 3). Note that it is easy to complement a graph in O(n2) (i.e. polynomial) time (e.g. flip 0’s and 1’s in the adjacency matrix). Thus f is computable in polyno mial time. Intuitively, saying that L1 P L2 means that “if L2 is solvable in polynomial time, then so is L1.” This is because a polynomial time subroutine for L2 could be applied to f(x) to determin e whether f(x) 2 L2, or equivalently whether x 2 L1. Thus, in sense of polynomial time computability, L1 is “no harder” than L2. The way in which this is used in NP-completeness is exactly the converse. We usu ally have strong evidence that L1 is not solvable in polynomial time, and hence the reduction is effectively eq uivalent to saying “since L1 is not likely to be solvable in polynomial time, then L2 is also not likely to be s olvable in polynomial time.” Thus,

this is how polynomial time reductions can be used to show that problems are as hard to solve as known difficult problems. Lemma: If L1 P L2 and L2 2 P then L1 2 P. Lecture Notes 63 CMSC 451 Lemma: If L1 P L2 and L1 =2 P then L2 =2 P. One important fact about reducibility is that it is transitive. In other words Lemma: If L1 P L2 and L2 P L3 then L1 P L3. The reason is that if two functions f(x) and g(x) are computable in polynomial t ime, then their composition f(g(x)) is computable in polynomial time as well. It should be noted that our te xt uses the term “reduction” where most other books use the term “transformation”. The distinction is subtle, but people taking other courses in complexity theory should be aware of this. NP-completeness: The set of NP-complete problems are all problems in the complex ity class NP, for which it is known that if any one is solvable in polynomial time, then they all are, and con versely, if any one is not solvable in polynomial time, then none are. This is made mathematically formal using the notion of polynomial time reductions. Definition: A language L is NP-hard if: L 0 P L for all L 0 2 NP: (Note that L does not need to be in NP.) Definition: A language L is NP-complete if: (1) L 2 NP and (2) L is NP-hard. An alternative (and usually easier way) to show that a problem is NP-complete is to use transitivity. Lemma: L is NP-complete if (1) L 2 NP and (2) L0 P L for some known NP-complete language L0. The reason is that all L00 2 NP are reducible to L0 (since L0 is NP-complete and hence NP-hard) and hence by transitivity L00 is reducible to L, implying that L is NP-hard. This gives us a way to prove that problems are NP-complete, once we know that on e problem is NP-complete. Unfortunately, it appears to be almost impossible to prove that one problem is N P-complete, because the definition says that we have to be able to reduce every problem in NP to this problem. Ther e are infinitely many such problems, so how can we ever hope to do this? We will talk about this next time with Cook’s theorem. Cook showed that there is one problem called SAT (short for boolean satisfiability) t hat is NP-complete. To prove a second problem is NP-complete, all we need to do is to show that our problem is in NP (and hence it is reducible to SAT), and then to show that we can reduce SAT (or generally some known NPC pr oblem) to our problem. It follows that our problem is equivalent to SAT (with respect to solvability in po lynomial time). This is illustrated in the figure below. Lecture 18: Cook’s Theorem, 3SAT, and Independent Set Read: Chapter 34, through 34.5. The reduction given here is similar, but not the same as the reduction given in the text. Recap: So far we introduced the definitions of NP-completeness. Recall that we m

entioned the following topics: P: is the set of decision problems (or languages) that are solvable in polynomia l time. NP: is the set of decision problems (or languages) that can be verified in polyn omial time, Lecture Notes 64 CMSC 451 Proving a problem is in NP Your problem Known NPC Proving a problem is NP−hard Resulting structure NPC NP Your reduction NP NPC NP P P NPC P SAT SAT Fig. 47: Structure of NPC and reductions. Polynomial reduction: L1 P L2 means that there is a polynomial time computable fu nction f such that x 2 L1 if and only if f(x) 2 L2. A more intuitive to think about this, is that i f we had a subroutine to solve L2 in polynomial time, then we could use it to solve L1 in polynomial time . Polynomial reductions are transitive, that is, if L1 P L2 and L2 P L3, then L1 P L3 . NP-Hard: L is NP-hard if for all L0 2 NP, L0 P L. Thus, if we could solve L in po lynomial time, we could solve all NP problems in polynomial time. NP-Complete: L is NP-complete if (1) L 2 NP and (2) L is NP-hard. The importance of NP-complete problems should now be clear. If any NP-complete p roblems (and generally any NP-hard problem) is solvable in polynomial time, then every NP-complete prob lem (and in fact every problem in NP) is also solvable in polynomial time. Conversely, if we can prove that any NP-complete problem (and generally any problem in NP) cannot be solved in polynomial time, then ever y NP-complete problem (and generally every NP-hard problem) cannot be solved in polynomial time. Thus all N P-complete problems are equivalent to one another (in that they are either all solvable in polynomial ti me, or none are). An alternative way to show that a problem is NP-complete is to use transitivity of P . Lemma: L is NP-complete if (1) L 2 NP and (2) L0 P L for some NP-complete language L0. Note: The known NP-complete problem L0 is reduced to the candidate NP-complete p roblem L. Keep this order in mind. Cook’s Theorem: Unfortunately, to use this lemma, we need to have at least one NPcomplete problem to start the ball rolling. Stephen Cook showed that such a problem existed. Cook’s theorem is q uite complicated to prove, but we’ll try to give a brief intuitive argument as to why such a problem might ex ist. For a problem to be in NP, it must have an efficient verification procedure. Thu

any set X can be described by choosing a set of objects. can be described as a boolean formula. where X is some structu re (e. This implies that neither of the subclauses involving x2 and x3 in the first two clauses can be satisfied. The proof would take about a full lecture (not c ounting the week or so of background on Turing machines). boolean-or (x_y) and boolean-and (x^y).) and P(X) is some property that X must satisfy (e . (x1 _ (x2 ^ x3)) ^ (x1 _ (x2 ^ x3)) ^ (x2 _ x3) ^ (x2 _ x3) is not satisfiable. or the path must visit every vertex. x3 = 0 On the other hand.) For example. the set of objects must fill the knapsack. and the l ogical operations x meaning the negation of x. a path. For example (x1 _ x2 _ x3) ^ (x1 _ x3 _ x4) ^ (x2 _ x3 _ x4) is in 3-CNF form. by the assignment x1 = 1. Similarly. we say that it is satisfiable if there is a way to assign truth values (0 or 1) to the variables such that the final result is 1. x2 = 0. but x1 cannot be set to satisfy them either. In fact. it would be one in which X is an assignment of boolean values (true/false. (As opposed to the case where no matter how you assign truth values the result is always 0. 3SAT is the problem of determining whether a formula in 3-CNF is satisfiable. We will not prove this theorem. (x1 ^ (x2 _ x3)) ^ ((x2 ^ x3) _ x1) is satisfiable.g. He reasoned that computers (which represent the most general Lecture Notes 65 CMSC 451 type of computational devices known) could be described entirely in terms of boo lean circuits. In showing that such a problem is in NP. . A literal is a variable or its negation x or x. Given a boolean formula. SAT: Given a boolean formula. a partition. In general. It turns out that it is possible to modify the proof of Cook’s theorem to show that the more restric ted 3SAT is also NP-complete. it turns out that a even more restricte d version of the satisfiability problem is NP-complete. a set.g. an assignment.s virtually all NP problems can be stated in the form. and hence in terms of boolean formulas. This sug gests the following problem. the certifica te consists of giving X. or you may use at most k colo rs and no two adjacent vertices can have the same color). 0/1) and P(X) could be any boolean formula. If any problem were hard to solve. A formul a is in 3-conjunctive normal form (3-CNF) if it is the boolean-and of clauses where each clause is the boolea n-or of exactly 3 literals.) Cook’s Theorem: SAT is NP complete. (Observe that the last two clauses imply that one of x2 and x3 must be true and the other must be false. which in tu rn can be described as choosing the values of some boolean variables. called the boolean satisfiability problem. so that the formula evaluates to true? A boolean formula is a logical formula which consists of variables xi. tru e/false) to the variables of the formula. since this should represent the hardest problem in NP to solve. “does there exists X such that P(X)”. and the verification involves testing that P(X) holds. etc. is there some way to assign truth values (0/1. Stephen Cook was looking for the most general possible proper ty he could. the property P(X) that you need to satisfy.

Let F be a boolean formula in 3-CNF form (the boolean-and of clauses. and y ou do not want to invite two enemies. If a boolean formula is given in 2SAT. represented by edges between them. NP-completeness proofs: Now that we know that 3SAT is NP-complete. The certifica te consists of the k vertices of V 0. The independent set problem arises when there is some sort of selection probl em.E) and an integer k does G contain a subset V 0 of k vertices such that no two vertices in V 0 are adjacent to one another. We will start with the independent set problem. f(F) = (G. So the corresponding optimization problem would be to find an independent set of the la rgest size in a graph. we will consider the simplest version of the problem. that is. 49: Reduction of 3-SAT to IS. However. (For example. each of which is the boolean-or of 3 literals) . but many pairs do not get along. a graph G and integer k.) Note that if a graph has an independent set of size k. then it has an independen t set of all smaller sizes. since we want to show that the problem is hard to solve. Lecture Notes 66 CMSC 451 Fig.As an aside. Clearly this can be done in polynomial time. there is no edge between them. 48: Independent Set. the graph shown in the figure below has an independent set (shown w ith shaded nodes) of size 4. For example. The proof involves two parts. That is. We wish to find a polynomial time computable function f that maps F into a input for the IS problem. v 2 V 0. 3SAT P IS. Thus. k). then everything cha nges. Secondly. but there are mutual restrictions pairs that cannot both be selected. then it is possible to determine its satisfiability in polynomial time. so we might talk about the problem of computing the i ndependent set with the largest total weight. by an inspection of the adjacency matrix. boolean formula polynomial time computable graph and integer no (in 3−CNF) yes F 3SAT f (G. This will mean that if we can solve the independent set problem for G and k in polynomial time. even a seemingly small change can be the difference between an efficient algorithm and none. such that F is satisfiable if and only if G has an independent se t of size k. we need to show that IS 2 NP. Independent Set (IS): Given an undirected graph G = (V. note that if we replace the 3 in 3SAT with a 2. we need to establish that IS is NP-hard. which can be done by showing that some known NP-complete problem (3SAT) is polynomial-time reducible to IS.k) IS Fig. Claim: IS is NP-complete. First. you want to invit e as many of your friends to your party. then we would be able to solve . we can use th is fact to prove that other problems are NP-complete. We simply verify that for each pair of vertex u. Often the vertices have weights.

Lecture Notes 67 CMSC 451 IS: If u is selected to be in V 0. k) such that the above elements are translated properly. IS: V 0 must contain at least k vertices. An important aspect to reductions is that we do not attempt to solve the satisfi ability problem. 1 x2 . 3SAT to IS Reduction k number of clauses in F. We want a function f. Our strategy will be to create one verte x for each literal that appears within each clause. Selecting a true literal from some cl ause corresponds to selecting a vertex to add to V 0. Equivalently.) The vertices are grouped into clause clusters. Given any reasonable encoding of F. (Remember: It is NP-complete. and the output is a graph G and integer k . and v is a neighbor of u. converts it into a pair (G. we will connect all the vertices in each clause cluster to each other. This enforces the condition that i f a literal is put in the IS (set to true) then its complement literal cannot also be true. What is to be selected? 3SAT: Which variables are assigned to be true. This forces the indepen dent set to pick one vertex from each clause. To keep the IS subroutine from selecting both a literal a nd its complement. x3) create an edge (xi. k). then xi must be false. We set k to the number of clauses. Example: Suppose that we are given the 3-CNF formula: (x1 _ x2 _ x3) ^ (x1 _ x2 _ x3) ^ (x1 _ x2 _ x3) ^ (x1 _ x2 _ x3): The reduction produces the graph shown in the following figure and sets k = 4. (Thus. x2. if there are m clauses in F. it is an easy programming exercise to create G (say as an adjacency matrix) in polynomial time. return (G. The input is a boolean formula F in 3-CNF.) So the function f must operate without knowledge of whether F is satisfiable. In order to keep t he IS subroutine from selecting two literals from some clause (and hence none from some other). Requirements: 3SAT: Each clause must contain at least one literal whose value it true. The idea is to translate the simi lar elements of the satisfiable problem to corresponding elements of the independent set problem. thus. Restrictions: 3SAT: If xi is assigned true. and there is not likely to be any polynomial time solution. xj) between all pairs of vertices in the cluster. IS: Which vertices are to be placed in V 0. which literals are assigned true. A formal description of t he reduction is given below. we will put an edge between each literal and its complement. We claim that F is satisfiable if and only if G has an indep endent set of size k. one literal from each clause is true. and vice versa. for each clause cluster (x1. there will be 3m vertice s in G. one for each clause.3SAT in polynomial time. which given any 3-CNF boolean formula F. for each vertex xi create edges between xi and all its complement vertices xi. for each clause C in F create a clause cluster of 3 vertices from the literals of C. then v cannot be in V 0.

because we cannot have two vertices labeled xi and xi in the same cl uster. we get an independent set of size k = 4. if G has an independent set V 0 of size k. there can be no edge of the form (xi. and x3 satifies t he third. Note that the literal x1 satisfies the first and last clauses. Observe that our reduction did not attempt to solve the IS problem nor to solve the 3SAT. Conversely. x2 satisfies the second. Finally the transformation clearly runs in polynomial time. Observe that by selecting the corresponding vertices from the clusters. because there are k clusters. Instead the reduc tion simply translated the input from one problem into an equivalent input to the other problem. V 0 is an independent set of size k. First observe that we mus t select a vertex from each clause cluster. while pres . xi) between the vertices of V 0. Lecture Notes 68 CMSC 451 Correctness Proof: We claim that F is satisfiable if and only if G has an indepe ndent set of size k. In our example. (We did not as sume that the formula was satisfiable. This completes the NP-completeness proof. and we cannot take two vertices from the same cluster (because they are all interconnected). the formula is satisfied by the assignment x1 = 1. Let V 0 den ote the corresponding vertices from each of the clause clusters (one from each cluster). Because we take vertic es from each cluster. then each of the k clauses of F must have at least one true literal. x3=0) x3 x2 x1 x x The reduction x1 2 3 x2 x2 x3 x1 x3 x1 x2 x 1 x x3 x1 x2 x3 x3 x2 x1 Fig. Also observe that the reduction had no knowledge of the solution to either problem. Thus. x2 = 1. nor did we assume we knew which variables to set to 1.x3 Correctness (x1=x2=1. This assignment is logically consistent. and because we cannot set a variable and it s complement to both be true. 50: 3SAT to IS Reduction for (x1 _ x2 _ x3) ^ (x1 _ x2 _ x3) ^ (x1 _ x2 _ x 3) ^ (x1 _ x2 _ x3). Consider the assignment in which we set all of these literals t o 1. and x 3 = 0. IfF is satisfiable.) This is bec ause computing these things would require exponential time (by the best known algorithms). there are no inter-cluster edges between them.

Vertex Cover (VC): A vertex cover in an undirected graph G = (V. Today we give a few more examples of reductions.E) and an integer k.E) is a subset of vertic es V 0 such that every vertex in the graph is either in V 0 or is adjacent to some vertex in V 0.E) is a subset o f vertices V 0 V such that every edge in G has at least one endpoint in V 0. We have discussed the facts that cliques are of interest in applications dealing with clustering. The dominati ng set problem (DS) is: given a graph G = (V. The dominating set proof is not given in our t ext.E) and an integer k. From these nodes all the links can be tested. The clique problem seeks to find a single clique of size k. does G have a k vertex subset whose induced subgraph is complete. The vertex cover problem (VC) is: given an undirected graph G and an integer k. does G have a subset V 0 of k vertices such that for each distinct u.erving the critical elements to each problem. A minimum sized dominating set will be a minimum set of locations such that every other location is reachable within 2 minutes from one of these sites. Vertex Cover. Some Easy Reductions: We consider some closely related NP-complete problems next . and Dominating Set Read: Chapt 34 (up through 34. The CLIQUE problem is obviously closely related to the independent set problem ( IS): Given a graph G does it have a k vertex subset that is completely disconnected. The vertex cover problem arises in various servicing applications. For example. vg 2 E. v 2 V 0. To save the space of installing the program on every computer in the network. Recall that to show that a problem is NP-complete we need to show (1) that the problem is in NP (i. fu.e. it suffices to install it on all the computers forming a vertex cover. and (2) that the problem is NP-hard. we can verify wh en an input is in the language). We create a graph in which two locations are adjacent if they are within 2 minutes of each other. Dominating set is useful in facility location problems. For example.5). Recap: Last time we gave a reduction from 3SAT (satisfiability of boolean formul as in 3-CNF form) to IS (independent set in graphs). does G have a vertex cover of size k? Dominating Set (DS): A dominating set in a graph G = (V. Lecture 19: Clique. does G have a dominating set of size k? Don’t confuse the clique (CLIQUE) problem with the clique-cover (CC) problem that we discussed in an earlier lecture. by showing that some known NP-complete prob lem can be reduced to this problem (there is a polynomial time function that transforms an input for one pr oblem into an equivalent input for the other problem). In other words. Clique (CLIQUE): The clique problem is: given an undirected graph G = (V. each of which is a clique. It is not quite as clear that the vertex cover problem is . and the cli que-cover problem seeks to partition the vertices into k groups. suppose we want to select where to place a set of fire stations such that every house in the city i s within 2 minutes of the nearest Lecture Notes 69 CMSC 451 fire station. you have a comput e network and a program that checks the integrity of the communication links.

dominating set is an example of a graph co vering problem. Given s uch a certificate we can easily verify in polynomial time that every edge is incident to one of these vertices. Independent set. n. then for any u. fu. G G G V’ is CLIQUE of iff size k in G iff V’ is an IS of size k in G V−V’ is a VC of size n−k in G Fig. implying that V 0 is an independent set for G. the following lemma makes this connection clear as well. Here the condition . Clearly this can be done in polynomial time. Thus. computes the number of vertices. Note: Note that in each of the above reductions. vg is not an edge of G. fu. Dominating Set: As with vertex cover. Lemma: Given an undirected graph G = (V. and then outputs (G. we have the following. these instances are equivalent. (ii) ) (iii): If V 0 is an independent set for G. Given suc h a certificate we can easily verify in polynomial time that all pairs of vertices in the set are adjacent. Theorem: VC is NP-complete. we can produce an equivalent instance of the VC problem in polynomial time. Lecture Notes 70 CMSC 451 IS P VC: We want to show that given an instance of the IS problem (G. implying that V − V 0 is a VC for G. vg in G. By the abo ve lemma. 51: Clique. and Vertex Cover. v 2 V 0 there is n o edge fu. vg in G. vg is not an edge of G. and outputs the pair (G. k). (iii) ) (i): If V −V 0 is a vertex cover for G. Proof: (i)) (ii): If V 0 is a clique for G. vg is an edge of G implying that fu. However. v 2 V 0. The reduction function f inputs G and k. (ii) V 0 is an independent set of size k for G.related. Clearly this can be done in po lynomial time. (iii) V − V 0 is a vertex cover of size n − k for G. this instance is equivalent. implying that V 0 is a clique in G. v 2 V 0. IS P CLIQUE: We want to show that given an instance of the IS problem (G. n − k). then for each u. k). and IS is an NP-complete problem. By the lemma above. we could eas ily translate it into an algorithm for the others. The following are equivalent: (i) V 0 is a clique of size k for the complement. k). The reduction function f inpu ts G and k. VC 2 NP: The certificate consists of the k vertices in the vertex cover. G. the reduction function did not know whether G has an independent set or not. Theorem: CLIQUE is NP-complete. In particular. we can produce an equivalent instance of the CLIQUE problem in polynomial time.E) with n vertices and a subset V 0 V of size k. then for each u. implying that there is an edge fu. It must run in polynomial time. if we had an algorithm for solving any one of these problems. implying that every edge in G is incident to a vertex in V − V 0. CLIQUE 2 NP: The certificate consists of the k vertices in the clique. So it does not have time to determine whether G has an independent set or which vertices are in the set. V 0 is an independent set for G.

Let I denote the number of isolated vertices and set k0 = k + I. How to we translate between these problems? The key difference is the condition. The fact that u was incident to edge fu. The certificate ju st consists of the subset V 0 in the dominating set. Initially G0 = G. Since it is not incident to any edges. Because incidence is a property of e dges. The main result of this section is just this. we will leave the edge fu. we will create a new sp ecial vertex. Now we can give the complete reduction. for each edge fu.is a little different. We want a polynomia l time function. Let VI denote the isolated vertices in G. this suggests that the reduction function maps edges of G into vertices in G0. Output (G0. If u is isolated it can only be dominated if it is included in the dominating set. In VC: “every edge is incident to a vertex in V 0”. This suggests the following idea (which does not quite work). Let G0 be the resulting graph. we need to show that G has a vertex . This reduction illustrated in the following figure. However the similarity suggests that if VC in NP-complete.wuvg and fv. and let I denote the number of isolated vertices. We still need to dominate the neighbor v. called wuv. k) for the VC problem . Obviously. Define an isolated vertex to be one that is incident to no edges. which given an instance of the vertex cover problem (G. We will insert a v ertex into the middle of each edge of the graph. k0) of the dominating set problem. The number of vertices to request for the dominating set will be k0 = k + I. To do this. As usual the proof has two parts. We choose vertex cover and show that VC P DS. then DS is likely to be NP-co mplete as well. if G is connected and has a vertex cover of size k. and replace the edge fu. vg in the graph as well. vg has now been replaced with the fact that u is adjacent to the corresponding vert ex wuv. Given the pair (G. This is still not quite correct though. First we show that DS 2 NP. each vertex is adjacent to the members of the dominating set. k0). In DS: “every vertex is either in V 0 or is adjacent to a verte x in V 0”. then it has a dominating set of size k (the same set of vertices).wuvg in G0. Theorem: DS is NP-complete. but the conve rse is not necessarily true. In other words. vg. Note that every step can be perfo rmed in polynomial time. k). such that an incident edge in G is mapped to an adjacent vertex in G0.wuvg and fv. and adjacency is a property of vertices. such that G has a vertex cover of size k if and only if G0 has a domina ting set of size k0.wuvg. as opposed to each edge being incident to each member of the dominating set. we create a graph G0 as follows. produces an instance (G0. Reducing Vertex Cover to Dominating Set: Next we show that an existing NP-comple te problem is reducible to dominating set. For each edge fu. Thus the translation must somehow map the notion of “incident” to “adjacent”. it does not need to be in the vertex cover. vg in G we create a new vertex wuv in G0 and add edges fu. Correctness of the Reduction: To establish the correctness of the reduction. In polynomial time we can determine whether every vertex is in V 0 or is adjacent to a vertex in V 0. vg with the two edges fu.

if there are any isolate d vertices in V 0. then V 00 = V 0 [ VI is a dominating set for G0. and wuv (because u has edg es going to v and wuv).cover of size k if and only if G0 has a dominating set of size k0. (We could have just as easily replaced it with v. we claim that if G0 has a dominating set V 00 of size k0 = k + I the n G has a vertex cover V 0 of size k. Conversely. 53: Correctness of the VC to DS reduction (where k = 3 and I = 1). we claim that we never need to use any of the newly created special ver tices in V 000. to the contrary there were an edg e fu. However. Lecture Notes 71 CMSC 451 f G k=3 G’ k’=3+1=4 Fig. v. wng .5. so it domin ates itself and these other two vertices. (This is shown in the lower middle part of the figure. and hence either it is in V 0 or else all of its neighbors are in V 0. By using u instead. contradicting the hypothesis that V 00 was a dominating set for G0. let V 000 = V 00 − VI be the remaining k vertices. Given a finite set S o f positive integers S = fw1. : : : . Thus wuv is dominated by the same vertex in V 00 Finall y. L et V 0 denote the resulting set after this modification. 52: Dominating set reduction. each of the nonisolated original vertices v is incident to at least one edge in G.v with u we dominate the same vertices (and potentially more). Lecture Notes 72 CMSC 451 Lecture 20: Subset Sum Read: Sections 34.) Observe that the vertex wuv is adjacent to only u and v. each of the special vertices wuv in G0 corresponds to an edge fu. first observe that all the isolated vertic es are in V 00 and so they are dominated. This is shown in the top part of the following figure.) We claim that V 0 is a vertex cover for G. F irst. If so. v is either in V 00 or adjacent to a vertex in V 00.5 in CLR. if some vertex wuv 2 V 000. we can add any vertices we like to make the size equal to k0. In particular. We might try to claim something like: V 000 is a vertex co ver for G. Note that all I isolated vertices of G0 must be in the dominating set. w2. If. vg in G implying that either u or v is in the vertex cover V 0. To see that V 00 is a dominating set. we still dominate u. vertex cover for G dominating set for G’ dominating set for G’ using original vertices vertex cover for G Fig. Observe that jV 00j = jV 0 [ VIj k+I = k 0 : Note that jV 0 [ VI j might be of size less than k + I. First we argu e that if V 0 is a vertex cover for G. Thus by replacing wu. vg of G that was not covered (neither u nor v was in V 0) then the special vertex wuv would not be ad jacent to any vertex of V 00 in G0. Second. because V 000 may have vertices that are not part of the origi nal graph G. Subset Sum: The Subset Sum problem (SS) is the following. In either case. then modify V 000 by replacing wuv with u. But this will not necessarily work.

It follows that if we can show that this simpler version is NP-complete . This problem is a simplified version of the 0-1 Knapsack problem. Note that an important consequence of this observation is that the SS problem is not hard when the numbers involved are small. We are given a knapsack of capacity W.2 The quantity n t is a polynomial function of n. we will s how that Vertex Cover (VC) is reducible to SS. this problem is NP-complete. we will show that in the ge neral case. vi = wi. Recall that in the 0-1 Knapsack problem. This is polynomial in n. the best we could hope to achieve would be to fill the knapsack entirely.and a target value. Thus. we see that the subset sum problem is equivalent to this simplifi ed version of the 0-1 Knapsack problem. I f t = 34 the answer would be no. So. The objective is to take as many objects as can fit in the knapsack’s capacity so as to maximize the value. Given S and t.) I n the simplest version. (ii) Some known NP-complete problem is reducible to SS. Dynamic Programming Solution: There is a dynamic programming algorithm which sol ves the Subset Sum problem in O(n t) time. Then the input size is O(nb). Consider the following example. 32g and t = 33: The subset S0 = f6.) Then. However. (This would occur for example if all the objects were made of the same material. 15. 12. (In the fractional knapsac k we could take a portion of an object. in polynomial time we can compute the sum of elements in S0. This would seem to imply that th e Subset Sum problem is in P. To show that SS is in NP. 6. Recall that in all NP-complete problems we assum e (1) running time is measured as a function of input size (number of bits) and (2) inputs must be encoded in a reasonable succinct manner. t. we want to know whether there exists a subset S0 S that s ums exactly to t. say. we are given a collection of objects. then certainly the more general 0-1 Knapsack problem (stated as a decision problem) is also NP-complete. 23. so the answer in this case is yes. we need to give a verification procedure. VC P SS. The value of t may be as large as 2b. SS is NP-complete: The proof that Subset Sum (SS) is NP-complete involves the us ual two elements. the certificate is just the indices of the numbers that form the subset S0. S = f3. So the resulting algorithm has a running time of O(n2b). using the fewest number of bits possible. 9. In particular. but exponential in b. that is. suppose that the value is the same as the weight. presented as a decision problem. . If the numbers involved are of a fixed number of bits (a con stant independent of n). We can add two b-bit numbers tog ether in O(b) time. (i) SS 2 NP. each wit h an associated weight wi and associated value vi. thi s running time is not polynomial as a function of the input size. 15g sums to t = 33. gold. In the 0-1 Knapsack we either take an object entirely or leave it. Let us assume that the numbers wi and t are all b-bit numbers represented in base 2. But there is a important catch. 12. and verify that this s um equals t. By setting t = W. then the problem is solvable in polynomial time.

2We will leave this as an exercise.For the remainder of the proof we show how to reduce vertex cover to subset sum. Lecture Notes 73 CMSC 451 How can we encode the notion of selecting a subset of vertices that cover all th e edges to that of selecting a subset of numbers that sums to t? In the vertex cover problem we are selecting v ertices. First number the edges of the graph from 1 through E. for 0 i n and 0 t0 . w2. but the formulation is. S[i. Thus. so would vertex cover. and in the subset sum problem we are selecting numbers. An Initial Approach: Here is an idea. so it seems logical that the reduction should map vertices into numbers. if subset sum were solvable in polynomial time. in which k = 3. 1 1 1 6 7 1 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 t . The ith row of this table can be computed in O (t) time. given the contents of the (i − 1)-st row. (Another way to think of this is that these bit vectors form the r ows of an incidence matrix for the graph. and 0 otherwise.) An example is shown below. wig that sums to t0. but gives a sense of how to proceed. which does not work. We want a polynomial time computable function f that maps an instance of the vertex cover (a graph G and i nteger k) to an instance of the subset sum problem (a set of integers S and target integer t) such that G has a vertex cover of size k if and only if S has a subset summing to t. The constraint that these vertices should cover all the edges must be mapped to the constraint that the sum of the numbers should equal the target value. Then represent each vertex vi as an E-element bit vector. where the j-th bit from the left is set to 1 if a nd only if the edge ej is incident to vertex vi. : : : . t0] = 1 if there is a subset of fw1. Let E denote the number of edges in the graph.

implying that the vertices form a vertex cover.0 0 6 e1 e2 e3 e8 e7 e6 e5 v2 v4 v3 e1 e2 e3 e4 e v 1 v 3 2 4 5 7 v v v v 1 5 v 4 e5 e6 e7 e8 v v v v Fig. then each edge has been covered by some vertex. Now. Conversely. (La ter we will consider how to encode the fact that there only allowed k vertices in the cover. If the subset is a vertex cover. 1111 : : : 1.) 1 0 1 1 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 t = 1 1 1 1 1 1 1 1 v v . 54: Encoding a graph as a collection of bit vectors. and so the logical-or will be a bit vector of all 1’s. suppose we take any subset of vertices and form the logical-or of the corre sponding bit vectors. then every edge will be covered by at least one of the se vertices. if the logical-or is a bit vector of 1’s.

First. then its value in the corresponding column would b e 2. (We could just take the logical-or of all the vertices. There are a number of problems. The target would be the number whose bit vector is all 1’s. i f both of the endpoints of some edge are in the vertex cover. and then the logical-or would certainly be a bit vectors of 1’s. 55: The logical-or of a vertex cover equals 1111 : : : 1. logical-or is not the same as addition.0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 7 3 e4 e5 e6 e7 e8 e1 e2 e v2 v4 v2 v3 v3 v4 e1 e2 e v 1 v 3 2 4 5 6 v v v v 1 5 6 7 v 3 e4 e5 e6 e7 e8 v v v v Fig. this is starting to feel more like the subset sum problem. we have no way of controlling how many vertices go into the vertex cover. Since bit vectors can be thought of as just a way of representing numbers in bin ary. For example. not 1. however.) Lecture Notes 74 CMSC 451 . Second.

(1) Create a set of n vertex values. but in binary 1101 + 0011 = 1000. Thus we can boost any value consisting of 1’s and 2’s to all 2’s. if use any base that is at least as large as base 3. and t into whatever base notation is used for the s . we will never generate a carry to the next position. But since this is the last column. To fix this problem. The second difference between logical-or and addition is that an edge may genera lly be covered either once or twice in the vertex cover. Observe that each column of the incidence matrix has at most two 1’s in any column. the yj ’s. In the target. For each slack variable we will put a 0. So.There are two ways in which addition differs significantly from logical-or. yE. except for a single 1-digit in the ith position. To fix this.E) and integer k for the vertex cover problem. it will not affect any of the other aspects of the cons truction. we can assume any bas e system we want. For each position where there is a 1. The i-th digit of yi is 1 and all others are 0. the final sum of these numbers will be a number c onsisting of 1 and 2 digits. We are only allowed to place only k vertices in the ver tex cover. there might be carries out of this l ast column (if k 4). we will create a set of E additional slack values. given the graph G = (V.g. In fact. We know t hat no digit of our sum can be a zero. Note that t he base of the number system is just for own convenience of notation. the size of the vertex cover. (3) Let t be the base-4 number whose first digit is k (this may actually span mu ltiple base-4 digits). Once the numbers have been formed. e. (4) Convert the xi’s. we c an supplement this value by adding in the corresponding slack value. we will get a sum consisting of 1’s and 2’s. observe that from the numb ers of our vertex cover. x2. The j-th digit is a 1 if edge ej is incident t o vertex vi and 0 otherwise. There is one last issue. where yi is a 0 followed by E base -4 digits.g. Thus. 1211 : : : 112. decimal or binary. we will not ha ve enough slack values to convert this into a 2. For example. Note that since we only have a base-4 representation. For each number arising from a vertex. e. T he value xi is equal a 1 followed by a sequence of E base-4 digits. e. Fo r 1 i E. (2) Create E slack values y1. The Final Reduction: Here is the final reduction. : : : . 00 000100000.. we must select exactly k of the vertex values. This does not provide us with a unique target value t. we will put a 1 in this additional column. x1. xn using base-4 notation. Thus. note that if there are any 0 values in the final sum. : : : . To see why this works. and whose remaining E digits are all 2. On the other hand. The first is the issue of carries. Our target will be the number 2222 : : : 222 (all 2’s). In fact we will use base 4 (for reasons to be seen below). we recognize that we do not have to use a binary (base-2) representation. to form the desired sum. the ith slack value will consist of all 0’s. y2.g. because eac h edge is incident to at most two vertices. they wi ll be converted into whatever form our machine assumes for its input representation. the 1101 _ 0011 = 1111. we will require that thi s column sum to the value k. We will handle this by adding an additional column.

since (because there are no ca rries) the corresponding column would be 0 in the sum of vertex values. in O(E2). xn. we take the corresponding slack variable. yEg and t. y1.ubset sum problem (e. and for each edge that is covered only once in V 0. We claim that these vert ices V 0 form a vertex cover. In particular. Thus. in fact. if S has a subset S0 that sums to t then we assert that it must sele ct exactly k values from among the vertex values. no edge can be left uncovered by V 0. Correctness: We claim that G has a vertex cover of size k if and only if S has a subset that sums to t. Conversely. Thus. 56. the leftmost digit of the sum will be k. Output the set S = fx1. the result ing subset sums to t. then we take the vertex values xi corresponding to t he vertices of V 0. It follows from the comments made earlier that the lower-order E digits of the resulting sum will be of the f orm 222 : : : 2 and because there are k elements in V 0. Observe that this can be done in polynomial time. Lecture Notes 75 CMSC 451 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 x x y y y y y y y y t 3 2 2 2 2 2 2 2 2 x Slack values Vertex values vertex cover size (k=3) x 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 . The constru ction is illustrated in Fig. the resulting digit position could not be equal to 2. base 10). IfGhas a vertex cover V 0 of size k. no matter what slack values we add .g. since the first digit must sum to k. : : : . and so this cannot be a solution to the subset sum prob lem. : : : .

0 0 0 0 0 0 .1 x x x 0 e e e e e e e e 1 0 0 0 0 0 0 0 1 1 1 1 1 1 5 6 7 4 3 2 1 2 3 4 5 6 7 8 1 2 3 4 5 6 7 8 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 0 1 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 Fig. 56: Vertex cover to subset sum reduction.

0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 y y y y y y y t 3 2 2 2 2 2 2 2 2 x Slack values Vertex values vertex cover size (take one for each edge that has only one endpoint in the cover) (take those in vertex cover) y 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1 x x x x x x 1 e e e e e e e e 1 0 0 0 0 0 0 0 1 1 1 1 1 1 5 6 7 4 3 2 1 2 3 4 5 .

but there are no guarantees how close it is to optimal. General Search Methods: There are a number of very powerful techniques for solvi ng general combinatorial optimization problems that have been developed in the areas of AI and operations research. Coping with NP-completeness: With NP-completeness we have seen that there are ma ny important optimization problems that are likely to be quite hard to solve exactly. which is not polynomial time.2) in CLRS. the target value t is at least as large as 4E 4n (where n is the number of vertices in G). we cannot simply give up at this point.6 7 8 1 2 3 4 5 6 7 8 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 0 0 0 1 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 Fig. 57: Correctness of the reduction. we needed to have large numbers . Lecture 21: Approximation Algorithms: VC and TSP Read: Chapt 35 (up through 35. In our d ynamic programming solution W = t. For example. so the DP algorithm would run in (n4n) time. Heuristics: A heuristic is a strategy for producing a valid solution. Lecture Notes 76 CMSC 451 It is worth noting again that in this reduction. or if lack of optimality is no t really an issue. since people do need solutions to these problems. How do we cope with NP-completeness: Use brute-force search: Even on the fastest parallel computers this approach is viable only for the smallest instances of these problems. This is worthwhile if all else fails. These go under . Since these are impo rtant problems.

the running time might be O(nd1=e). Such an algor ithm is given both the input. We will assume tha t costs are strictly positive values. the TSP optimization problem is to find the simple cycle of minimum cost in a digraph.names such as branch-and-bound. For example. Given an instance I of our problem. and it is equal to 1 if an d only if the approximate solution is the true optimum solution. their approximability varies considerably. and produces a solution that is within a guaranteed factor of the optimum solution. but not necessarily one of the smallest size. C(I) C(I) (n): Observe that (n) is always greater than or equal to 1. A-search. For any input size n. For a minimization problem we want C(I)=C(I) to be small. The performance of these approaches varies considerably from one problem to problem and instance to instance. Performance Bounds: Most NP-complete problems have been stated as decision probl ems for theoretical reasons. a running time like O((1=)2n3) would be such an example. For example. However underlying most of these problems is a natural optimization problem. Lecture Notes 77 CMSC 451 For some NP-complete problems. we say that the approximation algori thm achieves ratio bound (n). As approaches 0. The running time is a function of both n and . jIj = n we have max I C(I) C(I) . let C(I) be the cost o f the solution produced by our approximation algorithm. whereas O(n1=) and O(2(1=)n) are not. How do we measure how good an approximation algorithm is? We define the ratio bo und of an approximation algorithm as follows. Note that sometimes we are minimizing and sometimes we are maximizing. If the running time depends only on a polynomial function of 1= then i t is called a fully polynomialtime approximation scheme. and genetic algori thms. Although NP-complete problems are equivalent with respect to whether they can be solved exactly in polynomial time in the worst case. it is very unlikely that any approximation algor . if for all I. the clique optimization problem is to find the clique of maximum size. Approximation Algorithms: This is an algorithm that runs in polynomial time (ide ally). and a real value > 0. the VC optimiz ation problem is to find the vertex cover of minimum size. simulated annealing. Some NP-complete problems can be approximated arbitrarily closely. For example . An approximati on algorithm is one that returns a legitimate answer. and for a maxim ization problem we want C(I)=C(I) to be small. and returns an answer whose ratio bound is at most (1 + ) . But in some cases they can perform quite well. the running time increases beyond polynomial time. Such an algorithm is called a polynomial time approximation scheme (or PTAS for short). and let C(I) be the optimal solution.

58: The 2-for-1 heuristic for vertex cover. Here is a more formal proof of its approximation bound. this algorithm will be guaranteed to find a vertex cover whose size is at most twice that of the optimum. c an be approximated to within a factor of ln n. The first approach is to try something that seems like a “reasonably” good strategy. when not optimal.ithm exists. we put two into our cover. We will discuss two examples below. It is based on the following observation. G and opt VC The 2−for−1 Heuristic Fig. can often be proved to be close to optimal. Some NP-complete problems have PTAS’s. Consider an arbitrary edge (u . The approximation is given in the figure be low. but it is covered i n CLRS. Proof: Consider the set C output by ApproxVC. then P = NP. a heuristic. Here is an very simple algorithm. and recurse on the remaini ng edges. Observe that the size of C is exactly 2 jAj because we add two vertices for each such edge. (You cannot get much stupider than this!) T hen we remove all edges that are incident to u and v (since they are now all covered). We will not discuss this algorithm. that guarantees an approximation within a fact or of 2 for the vertex cover problem. One of its two vertices must be in the cover. but is described in CLRS) and the Euclidean TSP problem. but we do not know which one. much like NP-complete problems. We will not discuss this furt her. It turns out that many simple heuris tics. In fact. One example is the subset problem (which w e haven’t discussed. For example. Recall that a vertex cover is a subset of vertices such that every edge in the g raph is incident to at least one of these vertices. For every one vertex that must be in the cover. the set cover problem (a generalization of the vertex cover problem). Some NP-complete problems can be approximated to within a fixed constant factor . Let A be t he set of edges selected by the line marked with “(*)” in the figure. so it is easy to see that the cover we generate is at most twice the size of the optimum cover. The vertex cover optimization problem is to find a vertex cover of minimum size. if the graph TSP problem had an approximation algorithm with a ratio bound of an y value less than 1. Claim: ApproxVC yields a factor-2 approximation for Vertex Cover. that is. there are collections of problems which are “believed” to be hard to approximate and are equivalent in the sense that if any one can be approximated in polynomial time then they all can be. Vertex Cover: We begin by showing that there is an approximation algorithm for v ertex cover with a ratio bound of 2. Suffice it to say that the topic of approximation algorithms would fill another course. Many NP-complete can be approximated. However note that in the optimum VC one of these tw o vertices must have . v) in the graph. How does one go about finding an approximation algorithm. The idea of thi s heuristic is to simply put both vertices into the vertex cover. Let C be the optimum VC. For example. but the ratio bound is a (slow growing) f unction of n. This class is called Max-SNP complete.

until no more edges remain. Greedy Approximation for VC GreedyVC(G=(V. which form a maximal independent set of edges. We saw in the minimum spanning tree and shortest path problems that greedy strategi es were optimal. } It is interesting to note that on the example shown in the figure. This algorithm simply selects any edge. while (E is nonempty) do { let u be the vertex of maximum degree in G. In fact. This algorithm is illustrated in th e figure below. Can we prove that the greedy heuristic always outperfo rms the stupid 2-for-1 heuristic? The surprising answer is an emphatic “no”. Namely. add u to C. (For minimization prob lems we want a lower bound. and thus the size of C is at least jAj. G and opt VC The Greedy Heuristic Fig. and adds both vertices to the cover. remove from E all edges incident to u.) The bound should be related to someth ing that we can compute in polynomial time. } return C. Select the vertex with the maximum degree. Then delete all the edges that are incident to this vertex (since they have been cove red). Instead. Put thi s vertex in the cover. the greedy he uristic actually succeeds in finding the optimum vertex cover.v) be any edge of E add both u and v to C remove from E all edges incident to either u or v } return C. it can be shown that the greedy heuristic does .E)) { C = empty-set. Thus we have: jCj 2 = jAj jC j ) jCj jCj 2: Lecture Notes 78 CMSC 451 2-for-1 Approximation for VC ApproxVC { C = empty-set while (E is nonempty) do { (*) let (u. Here is the greedy heuristic. T his is greedy strategy.been added to the VC. 59: The greedy heuristic for vertex cover. The Greedy Heuristic: It seems that there is a very simple way to improve the 2for-1 heuristic. since a vertex of high degree covers the maximum number of edges. In this case. for maximization problems an upper bound. the bound is related to the set of edges A. Repeat the algorithm on the remaining graph. why not c oncentrate instead on vertices of high degree. } This proof illustrates one of the main features of the analysis of any approxima tion algorithm. that we need some way of finding a bound on the optimal solution.

Given a set of edges A formi ng a tour we define c(A) to be the sum of edge weights in A. (We leave Lecture Notes 79 CMSC 451 this as a moderately difficult exercise. using.w 2 V c(u. Shortcut tour start Optimum tour start MST Twice−around tour Fig. but we will not discuss it. for example. Here is how the algorithm works. v) denote the weight on edge (u. once in each direction. Let c(u. We shall see that if the edge weights sat isfy the triangle inequality.w): There are many examples of graphs that satisfy the triangle inequality. Therefore. Another example is if we are given a set of points in the plane. It can be shown that the ratio bound grows as (log n). We can compute MST’s efficiently. v) + c(v. either Kruskal’s or Prim’s algorithm. That is. where n is the number of vertices. Intuitively. For many of the applications of TSP. The key insight is to observe that a TSP with one edge removed is a spanning tre e. this says that the direct path from u to w. the problem satisfies something called the triangle inequality. and define a complete graph on these points.) Thus. . Last time we mentioned that TSP (posed as a decisi on problem) is NP-complete.5. then it will satisfy the triangle inequality. and we want to find a cycle that visits all vertices and is of minimum cost. the cost of the minimum TSP tour is at least as large as the cost of the MST. the tour that it produces cannot be worse than twice the cost of the optimal tour. The figure below shows an example of this. it should also be pointed out that the vertex cover constructed by the greedy heuristic is (for typical graphs) smaller than that one computed b y the 2-for-1 heuristic.w) c(u. although this algorithm does not prod uce an optimal tour. is never longer than an indirect pat h. given any weighted graph. For exam ple. then we will have an approximation for TSP. However it is not necessarily a minimum spanning tree. it can perform arbitrarily poorly compared to the optimal algorithm.not even have a constant performance bound. then the triangle inequality is also satisfied. v) is defined to be the Euclidean distance between these points. v) to be the shortest path length between u and v (computed. v. 60: TSP Approximation. Traveling Salesman Problem: In the Traveling Salesperson Problem (TSP) we are gi ven a complete undirected graph with nonnegative edge weights. s ay by the Floyd-Warshall algorithm). there is a slightly more complex version of t his algorithm that has a ratio bound of 1. When the underlying cost function satisfies the triangle inequality there is an approximation algorithm for TSP with a ratio-bound of 2.) However. v). so it would probably be wise to run both algorithms and take the better of the two. More formally. then this is possible. where c(u. (In fact. for all u. Given any free tree there is a tour of the tree called a twice around tour that traverses the edges of the tree twice. If we can find some way to convert the MST into a TSP tour while increasing its cost by at most a constant factor. if we define c(u.

and let w(u. Let T be the minimum spanning tree. since we can remove any edge of H resulting in a spanning tree. and so we have c(H) 2c(T): Combining these we have c(H) 2 c(T) c(H ) ) c(H) c(H) 2: Lecture 22: The k-Center Approximation Read: Today’s material is not covered in CLR. called centers. and Lecture Notes 80 CMSC 451 TSP Approximation ApproxTSP(G=(V.E)) { T = minimum spanning tree for G r = any vertex L = list of vertices visited by a preorder walk ot T starting with r return L } since T is the minimum cost spanning tree we have c(T) c(H ): Now observe that the twice around tour of T has cost 2c(T). The condition is that you are to minimize the maximum distance that any resident of the city must drive in order to arrive at the nearest store . since every edge in T is hit twice.) The triangle inequality assures u s that the path length will not increase when we take short-cuts. In the k-center problem we are given an undirected graph G = (V.E) denote the graph.E) with nonnegative edge weights. but we can make it simple by short-cutting. The company asks you to determine the best locations for these stores. we skip over previously visited vertices. when we short-cut an edge of T to form H we do not increase the cost of the tour.This path is not simple because it revisits vertices. let G = (V. Facility Location: Imagine that Blockbuster Video wants to open a 50 stores in s ome city. Proof: LetH denote the tour produced by this algorithm and letH be the optimum to ur. then this is an instance of the k-center problem. such that the maximum distance betw een any vertex in V and its nearest center in C is minimized.) More formally. Notice that the final order in which vertices are visited using the short-cuts is exactly the same as a preorder traversal of the MST. and we are given an integer k. v) denote the weight . that is. (The optimization problem seeks to minimize th e maximum distance and the decision problem just asks whether there exists a set of centers that are within a given distance. (In fact. By the triangle inequality. any subsequence o f the twice-around tour which visits each vertex exactly once will suffice. If we model the road network of the city as an undirected graph whose edge weigh ts are the distances between intersections. Th e problem is to compute a subset of k vertices C V . Claim: Approx-TSP has a ratio bound of 2. As we said before.

we define the overall bottleneck distance to be D(C) = max ci2C D(ci): . u) because G is undirected. 61: The k-center problem with optimum centers ci and neighborhood sets V (c i). define: V (ci) = fv 2V jd(v. This will be used in our proof.of edge (u. let d(u. For each vertex v 2 V we can ass ociate it with its nearest center in C. ci) d(v. ci): Lecture Notes 81 CMSC 451 6 5 5 4 9 5 8 6 8 4 5 7 V(c3) Input graph (k=3) Optimumum Cost = 7 c1 c3 c2 V(c2) V(c1) 6 5 9 5 6 7 6 4 5 8 8 9 5 9 5 6 7 6 Fig. Finally. v 2 V . For each cen ter ci 2 C we define its neighborhood to be the subset of vertices for which ci is the closest center. (T hese are the houses that are closest to this center. v) = w(v. (This is the nearest Blockbuster store to your house). V (c2). cj). See Fig. For each pair of vertices. that is. (Note that the shortest path distance satisfies the triangle inequality. u. (w(u. The bottleneck distance associated with each center is the distance to its farthest vertex in V (ci).) We assume that all edge weights are nonnegativ e. v). that is. : : : . for i 6= jg: Let us assume for simplicity that there are no ties for the distances to the clo sest center (or that any such ties have been broken arbitrarily). Then V (c1). 61. v) = d(u. V (ck) forms a partition of the vertex set of G.) Consider a subset C V of vertices. th e length of the shortest path from u to v. v) denote the distance between u to v. D(ci) = max v2V (ci) d(v.) More formally. the centers.

let d[u] denote the dista nce to the nearest center. the number of possible subse ts is n k = (nk). This the bottleneck vertex for fc1g. We can modify Dijkstra’s algorithm to operate a . it is not opt imal. it is highly unlikely that a significantly more efficient exact alg orithm exists in the worst-case. So let us just make it the next center. Given this notation.This is the maximum distance of any vertex from its nearest center.E). In Fig. called c2. We would like to select the next center so as to reduce this distance. A brute force solution to this problem would involve enumerating all k-element of subsets of V . the final three greedy centers are shaded. But there is an easier way. Here is a summary of the algorithm. One way to solve the distance computation step above would be to i nvoke Dijkstra’s algorithm i times. Greedy Approximation Algorithm: Our approximation algorithm is based on a simple greedy algorithm that produces a bottleneck distance D(C) that is not more than twice the optimum bottleneck di stance. The decision-problem formulation of the k-center problem is NP-complete (reducti on from dominating set). and computing D(C) for each one. in the figure below). Again we compute the distances from each vertex to its nearest center. 62(d). and the final bottleneck distance is 11. Although the greedy approach has a certain intuitive appeal (because it attempts to find the vertex that gives the bottleneck distance. We begin by letting the first center c1 be any vertex in the graph (the lower left vertex. 62(d)). c2g. Repeat this until all k center s have been selected. Then again we compute the distances from each vertex in the graph to the clo ser of c1 and c2. then this an exponential number of subset s. letting n = jV j and k. 62(c) where dashed lines indicate which vertices are closer to which center). Given that the problem is NP-complete. 62(b)). s ay. We know from Dijkstra’s algorithm how to compute the shortest path from a single s ource to all other vertices in the graph. This distanc e is critical because it represents the customer that must travel farthest to get to the nearest facility. In the example shown in the figure. Consider the vertex that is farthest from this center (the upper right vertex at distance 23 in the figure). we can now formally define the problem. find a subset C V of size k such that D(C) is minimized. and then puts a center right on this vertex). For each vertex u. k-center problem: Given a weighted undirected graph G = (V. We will show that there does exist an efficient approximation algorithm for the pro blem. wh ich beats the 11 that the greedy algorithm gave. Again we consider the bottleneck vertex for the current centers fc1. If k is a function of n (which is reasonable). and an integer k jVj. the bottl eneck vertex. We place the next center at this vertex (see F ig. However. the optimum solution (shown on the right) has a bottleneck cost of 9. (See Fig. Compute the distances between this vertex and all the other vertices in the graph (Fig.

it set s d[s] = 0 and pred[s] = null. In Lecture Notes 82 CMSC 451 9 6 11 9 4 (d) 6 (b) (c) 5 5 8 6 8 5 4 6 7 6 9 c2 c3 c2 c1 c1 c1 8 5 Greedy Cost = 11 (a) 9 6 8 5 4 6 7 5 6 9 5 19 6 14 12 14 19 5 8 9 6 8 5 4 6 7 5 6 9 5 23 5 6 4 9 5 11 6 . In particular.s a multiple source algorithm. in the initialization of Dijkstra’s single source algorithm.

Under the reasonable assumption that E V . 63: Worst-case for greedy. If we had instead chosen the vertex in the middle. which is bett er by a factor of 2. o2. Approximation Bound: How bad could greedy be? We will argue that it has a ratio bound of 2. Let D(G) denote the bottleneck distance for G. this is O(E log V ). consider a set of n + 1 vertices arranged in a linear graph. Suppose it pic ks the leftmost vertex. we do this for all the vertices of C. Let D = D(O) be the optimal bottleneck distance. let gk+1 denote the next center that would have been added next. Let G = fg1. The greedy algorithm might pick any initial vertex that it likes. 62: Greedy approximation to k-center. Greedy Approximation for k-center KCenterApprox(G. k) { C = empty_set for each u in V do // initialize distances d[u] = INFINITY for i = 1 to k do { // main loop Find the vertex u such that d[u] is maximum Add u to C // u is the current bottleneck vertex // update distances Compute the distance from each vertex v to its closest vertex in C. 64. the overall running time is O(kE log V ). denoted d[v] } return C // final centers } Lecture Notes 83 CMSC 451 the modified multiple source version. Let O = fo1. g2. : : : . Notice that the distance from . To see that we can get a factor of 2. in which all edges are of weight 1. okg denote the centers of the optimal solution (shown a s black dots in Fig. : : : . The final greedy algorithm involves running Dijkstra’s algorithm k times (once for each time through the for-loop). Also. t hat is. We want to show that this approximation algorithm always produces a final distan ce D(C) that is within a factor of 2 of the distance of the optimal solution. then the maximum distance would only be n=2. Opt Greedy Cost =n/2 Cost = n Fig. Then the maximum (bottleneck) distance is the distance to the rightmost vertex which is n . and the lines show the partition into the neighborhoods for each of these points). Re call that the running time of Dijkstra’s algorithm is O((V + E) log V ). Thus. gkg be the centers found by the greedy approximation (s hown as white dots in the figure below).8 12 9 6 8 5 4 6 7 6 9 5 Fig. the bottleneck vertex for G.

gj) D(G). gj) D(G). gj) 2D . and hence we have d(gi. You a re given a pair (X. it is selected to be at the maximum (bottleneck) distance from all the previous centers. the maximum dist ance between any pair of centers decreases. Bin packing is covered as an exercise in CLRS. each belongs to V (om) for some m. S2. Since D is the bottleneck distance for O. : : : . By concatenating these tw o paths. it follows that there exists a path of length 2D from gi to gj . Set Cover: The set cover problem is a very important optimization problem. that at least two centers of G0 are in the same set V (om) for some m . gk. Therefore. Because there are k centers in O. gj) 2D. gk+1g be the (k + 1)-element set consisting of the greedy centers together with the next greedy center gk+1 First observe that for i 6= j. Proof: Let G0 = fg1. g2. <D >D* o3 o4 o5 <D o1 g1 g2 g3 g6 g5 g4 o2 opt opt Fig. that is. The proof involves a simple application of the pigeon-hole principal . As we add more centers. D(G) d(gi. The greedy centers are give n as white dots and the optimal centers as black dots. Theorem: The greedy approximation has a ratio bound of 2.gk+1 to its nearest center is equal D(G). from which the desired ratio follows. d(gi. we know that the distance from gi to ok is of length at most D and similarly the distance from ok to gj is at most D. x2. 64: Analysis of the greedy heuristic for k = 5. This follows as a result of our greedy selection strategy. the greedy centers g4 and g5 are both in V (o2)). The regions represent the neighborhood sets V (oi) for the optima l centers. that is D(G)=D 2.3. Lecture 23: Approximations: Set Cover and Bin Packing Read: Set cover is covered in Chapt 35. : : : . . and k + 1 elements in G0. Let these be denoted gi and gj .F) where X = fx1. all the cente rs are at least this far apart from one another. it follo ws from the pigeon-hole principal. (In the figure. xmg is a finite set (a domain of elements) and F = fS1. But from the comments above we have d(gi. Since the final bottleneck distance is D(G). As each center is selected. Lecture Notes 84 CMSC 451 Each gi 2 G0 is associated with its closest center in the optimal solution.

that the approximation factor of lnm0 where m0 m is th e size of the largest set in F. and each vertex covers the subset of incident edges. the size of the underlying domain. You want to put up the fe west cameras to see all the paintings. For example. The domain to be covered are the ed ges. Complexity of Set Cover: We have seen special cases of the set cover problems th at are NP-complete. this is not true for the general Lecture Notes 85 CMSC 451 set cover problem. (This is a collection of sets over X. the VC approximation relies on the fact that each element of the domain (an edge) is in exactly 2 sets (one for each of its endpoints). Greedy Set Cover Greedy-Set-Cover(X. such that every element of X belongs to at least one set of F. S1 S2 S3 S4 S5 S6 Fig. In fact. Unfortuna tely. unless P = NP. suppose you w ant to set up security cameras to cover a large art gallery. their proof is more complicated. but it cannot be applied to generate a factor2 approximation for set cover. Consider t he example shown below. The optimum set cover consists of the three sets fS3.: : : . it is known that there is no constant factor approxi mation to the set cover problem. Thus. From each possible camera position. (The book proves a somewhat stronger result. 65: Set cover. you can see a certain subset of the paintings.) Greedy Set Cover: A simple greedy approach to set cover works by at each stage s electing the set that covers the greatest number of “uncovered” elements. the greed y heuristic. Today we will show that there is a reasonable approximation algorithm. S5g. In particular. vertex cover is a type of set cover problem. where m = jXj. Set cover can be applied to a number of applications. S4. Sng is a family of subsets of X. There is a factor-2 approximation for the vertex cover problem. Each such subset of paintings is a set in your system.S . F) { U = X // U are the items to be covered C = empty // C will be the sets in the cover while (U is nonempty) { // there is someone left to cover select S in F that covers the most elements of U add S to C U = U . the decision-problem formulation of set cover (“do es there exist a set cover of size at most k?”) is NP-complete as well. that is X = [ Si2C Si: The problem is to find the minimum-sized subset C of F that covers X. because set cover is one of the most powerfu l NP-complete problems. Consider a subset C F. which achieves an approximation bound of lnm. This is unfortunate. For example. However.) We say that C cove rs the domain if every element of X is in some set of C.

over and over again. then S2 (since it covers 2 o f the remaining 3) and finally S3. 1 + x ex. However we will show that the greedy set cover heuristic nevers performs worse t han a factor of lnm.) Initially. we need one important mathematical inequality. Theorem: Greedy set cover has the ratio bound of at most lnm where m = jXj. S2 is chosen. S6} S6 Greedy: {S1. (The two functions are equal wh en x = 0. and S6 have 16 elements. We remove al l the covered elements. S5. We know that there is a cover of size c (the . S6} S5 S4S3 S2 S1 Fig. then S6 (since it covers 3 out of the remaining 6). Proof: Let c denote the size of the optimum set cover. if we choose poorly. Consider the following example. S3. but it is possible to redesign the example such that there are no ties and yet the algorithm has essentially the same ratio bound. We will show that g=c lnm. but we are correct to within 1 set. Now S2. The pattern repeats. but I think it is easier to understand. Thus. S4.) Now. Lecture Notes 86 CMSC 451 Proof: We use the fact that for all x.) There were many cases wher e ties were broken badly here. Again. each of size 16. and if we raise both sides to the cth p ower. whereas the optimal set cover has size 3. the greedy algorithm will first select sets S1. S4 (size 2) and finally S5 and S6 (each of size 1). (Recall the lg denotes logarithm base 2. we have the desired result. The theorem of the approximation bound for bin packing proven here is a bit weak er from the one in CLRS. (Note that this is natural log. Initially all three sets S1. if we substitute −1=c for x we have (1 − 1=c) e−1=c. but we picked roughly lgm. Thus. where m = jXj. for a ratio bound of (lgm)=2. the optimum cover consisted of two sets. choosing S3 (size 4). not base 2. Lemma: For all c > 0. The optimal set cover consists of sets S5 and S6.} return C } For the example given earlier the greedy-set cover algorithm would select S1 (si nce it covers 6 out of 12 elements). S5 and S6 all cover 8 of the remaining elements. there are m0 = m elements left to be covered. Optimum: {S5. and let g denote the size of the greedy set cover minus 1. If ties are broken in the worst possible way. it would return a set cover of size 4. What is the approximation factor? The problem with the greedy set cover algorith m is that it can be “fooled” into picking the wrong set. 1− 1 c c 1 e : where e is the base of the natural logarithm. S2. S5.) Before giving the proof. (This is not quite what we wanted. 66: An example in which the Greedy Set cover performs poorly.

Bin Packing: Bin packing is another well-known NP-complete problem. we know that we can cover these m1 elements with a cover of size c (the optimal cover). we still have some element remaining to be covered. It will simplify the presentation to assume that 0 < si < 1.optimal cover) and therefore by the pigeonhole principle. it will select a set that covers at least this many elements. if every set covered less than m0=c elements. Thus. which is a v ariant of the knapsack problem. leaving at most m2 = m1(1 − 1=c) =m0(1 − 1=c)2 elements remaining. if we multiply by eg=c and take natural logs we get that g satisfies: eg=c m ) g c ln m: This completes the proof. the example shown above in which the approximation bound is (lgm )=2 is not “typical” of set cover instances. we are i nterested in the largest value of g such that 1 m 1 − 1 c g : We can rewrite this as 1 m 1 − 1 c cg=c : By the inequality above we have 1 m 1 e g=c : Now. there must be at least one set that covers at least m0=c elements. We want to put these objects into a set of bins. Each bi n can hold a subset of objects .) Since the greedy algorithm selects the larges t set. How long can this go on? Consider the largest value of g such that after removin g all but the last set of the greedy cover. Thus. t hen no collection of c sets could cover all m0 elements. Applying the argument again. where si denotes the size of the ith object. The number of elements that remain to b e covered is at most m1 = m0 − m0=c = m0(1 − 1=c). (Since otherwise. Even though the greedy set cover has this relatively bad ratio bound. and hence there exists a subset that covers at least m1=c elemen ts. If we apply this argument g times. it seems t o perform reasonably well in practice. each time we succeed in covering at least a f raction of (1 − 1=c) of the remaining elements. We are given a set of n objects. Then the number of elements that remain is uncovered after g sets have been chosen by the greedy algorithm is at most mg = m0(1 − 1=c)g.

: : : . Proof: Consider an instance fs1. and even if we were to fill each bin exactly to its capacity. so if i is the last index (i = bff) then i+1 = 1. (In fact. (The reduction is from the knapsack problem. However. We put this object in this bin. and hence first-fit would never have started to f ill the second bin. that is.) Lecture Notes 87 CMSC 451 Bin packing arises in many applications. We claim that ti + ti+1 1. Consider bins i and i + 1 filled by first-fit. We take each object in turn. We start with an unlimited number of empty bins. and bff denote the number of bins used by first-fit. and find the first bin that has space to hold this object. This is true. and just consider the sizes of the objects. For example. if the optimal solution uses b bins. We claim that first-fit uses at most twice as many bins as the optimum. The problem is to partition the objects among the bins so as to use the fewest possible bins. we would need at least S bi ns. Let S = P i si denote the sum of all the object sizes. we claim that bff 2S. Assume that indexing is cy clical. then you can reduce the pro blem into this form by simply dividing all sizes by the size of the bin. since no bin can hold a total capacity of m ore than 1 unit.) Next. we would need at least dSe bins. and first-fit uses bff bins. (Note that if your bin size is not 1. The algorithm is illustrated in the figu re below. called the fir st-fit heuristic. 67: First-fit Heuristic. Many of these applications involve not only the size of the object but their geometric shape as well. preferring to keep everything in the first bin. then bff b 2: 4 5 2 1 3 6 7 s s s s s s s Fig. the decision problem is still NP-com plete.whose total size is at most 1. If not. since the number of bins is an integer. or cutting the maximum number of pieces of certain shapes out of a piece of sheet metal. then the contents of bins i and i + 1 could both be put into the same bin. sng of the bin packing problem. First observe that b S. let ti denote the total size of the obj ects that first-fit puts into bin i. even if we ignore the geometry. these include packing boxes into a t ruck. Thus we have: . Let b denote the optimal number of bins.) Here is a simple heuristic algorithm for the bin packing problem. Theorem: The first-fit heuristic achieves a ratio bound of 2. To see this.

both good and bad. can you establish a lower bound?) If your solution is exponential time. you mi ght consider an approximation algorithm. After you have isolated the good desi gns. There is still much more to be learned about algorithm design. polynomial time reductions. The world is full of heuristics. but it may save you a few weeks of wa sted programming time. Still another direction might be to study numerical algorithms (as covered in a course on numerical analysis). which hides many of details of the running time (e.g. as well as a theoretical sense. NP-completeness: (Chapt 34. If you cannot prove a ratio bo und. 3-coloring to clique cover. . randomized algorithms. A good profiling tool can tell you which subroutines are taking the most time. You should develo p a good heuristic.2. Prototype to generate better designs: We have attempted to analyze algorithms fr om an asymptotic perspective. which considers how to design algorithms that are both ef ficient in a practical sense. You will likely an algorithm design problem that will involve one of these t wo techniques. a n emerging area is the study of algorithm engineering. but giv e a general perspective for separating good designs from bad ones. chances are that it is not correct at all. wh ich we have largely ignored.g. and if possible. constant factors). but we have cover ed a great deal of the basic material. parallel algorithms. 3SAT to Independent Set (IS). One direction is to specialize in some particular area. Do not forget DFS and DP. run many experiments to see how good the actual performance is. Can it be improved?: Once you have a solution.) Basic concepts: Decision problems. or approximation algorithm s. NP-completeness reductions: You are responsible for knowing the following reduct ions. All-Pairs Shortest paths: (Chapt 25. Finally. Writing proofs is not always easy. string pa ttern matching. but I will not ask too many detailed questio ns.coding. try to come up with a better one. polynomial time. Another direction is to gain a better understanding of average-case analysis. Still too slow?: If your problem has an unacceptably high execution time. Independent Set to Vertex Cover and Clique. the class P. Lecture Notes 89 CMSC 451 Material for the final exam: Old Material: Know general results. If you cannot see why it is correct. Is there some reason why a better algorithm does not exist? (That is. prove a ratio bound for your algorithm. certificates an d the class NP. then maybe your problem is NP-hard.) Floyd-Warshall Algorithm: All-pairs shortest paths. Running time O(V 3). computational geometry. It would be easy to devote an entire semester to any one of these topics. and those are the ones you shoul d work on improving. e. arbitrary edge weights (no n egative cost cycles). or to consider general search strategies such as simulated annealing. then it is time to start prototyping and doing empirical tests to establish the real constant factors.

Remember that you a re trying to translate the elements of one problem into the common elements of the other problem. NP-complete reductions can be challenging. k-center: Ratio bound of 2.2. Asymptotic analysis is based on two simplifying assumptions. since modifications of these will likely appear on the final. which captures the es sential growth rate properties. TSPopt MST). B 2 NP. Bin packing: Ratio bound of 2. First suppose that you have a solution to x and show how to map this to a solution for f(x). This means that you want to find a polynomial time function f that maps an instance of A to an instance of B. Set Cover: Ratio bound of lnm. It is also a good idea to understand all the reductions that were used in the ho mework solutions. Next. which hold in most .Vertex Cover to Dominating Set.) We would like a simple way of representing complex functions. Many approximation algorithms are simple. Asymptotics: The formulas that are derived for the running times of program may often be quite complex. If you cannot see how to solve the pr oblem. by showing that x 2 A if and only if f( x) 2 B. so make sure that understand the ones that we have done either in class or on homework problems. This basically involves specif ying the certificate. For some known NP-complete problem A. Explain that you know the temp late.. A P B. Explain which elements of problem A will likely map to which elements of problem B.. When designing algorithms. so don’t blow it. (Most are based on simple greedy heuri stics.g. Vertex Cover to Subset Sum. 35.) The key to proving many ratio bounds is first coming up with a lower bound on the optimal s olution (e. This almost always easy. T hen suppose that you have a solution to f(x) and show how to map this to a solution for x. Approximation Algorithms: (Chapt.g. provide an upper bound on the cost of your heuristic relative to thi s same quantity (e. up through 35. (Make sure to ge t the direction correct!) Show the correctness of your reduction. the shortcut twice-around tour for the MST is at most twice the MST cost). All NP-complete proofs have a very specific form. Suppose that you want to prove that some problem B is NP-complete. TSP with triangle inequality: Ratio bound of 2.) Vertex cover: Ratio bound of 2. the main purpose of the analysis is to get a sense for the trend in the algorithm’s running time. If you cannot figure out what f is. (An exact analysis is probably best done by implementing the algorithm and measuring CPU seconds. and try to fill in as many aspects as possible. I try to make at least one reduction on the exam similar to one that you have se en before. This is the purpose of asymptotics. The certificate is almost always the thing that the problem is asking you to fin d. here are some suggestions for maximizing partial credit. where m = jXj. Lecture Notes 90 CMSC 451 Supplemental Lecture 1: Asymptotics Read: Chapters 2–3 in CLRS. at least tell me what you would like f to do .

we will ignore constant factors. Asymptotic Notation: To represent the running times of algorithms in a simpler f orm.000 The clear lesson is that as input sizes grow. we use asymptotic notation. For example.001 sec 1 100 1 sec 0.001 sec 0. which will will express mathematically as T (n) 2 (n3). It may be the case that one function is smaller than another asymptotically. Large input sizes: We are most interested in how the running time grows for larg e values of n. the performance of the asymptotica lly poorer algorithm degrades much more rapidly.01 sec 100 1000 17 min 0. The justification for considering large n is that if n is small. But as n becomes larger the relative differences in running time become much greater. these as sumptions are reasonable when making comparisons between functions that have significantly different behaviors .) For small n (e. Intuitively. For example. one whose running time is T1(n) = n3 and another whose runnin g time is T2(n) = 100n.1 sec 10. This intuitive definition is fine for informal use. Most of the algorithms that we will study this semester wi ll have both low constants and low asymptotic running times. By ignoring constant fac tors. what we want to say with “f(n) 2 (g(n))” is that f(n) and g(n) are . and n0 such that 0 c1g(n) f(n) c2g(n) for all n n0g: Lecture Notes 91 CMSC 451 Let’s dissect this definition. Ignore constant factors: The actual running time of the program depends on vario us constant factors in the implementation (coding tricks. which essentially represents a function by its fastest growing term and ignores constant factors. For the most part. suppose we have an algorithm whose (exact) worst-case running time is given by t he following formula: T(n) = 13n3 + 5n2 −17n + 16: As n becomes large.000 11. speed of the underlying hardware. Assuming one million operations per second. in any particular appl ication. n is a fixed value. Definition: Given any function g(n). suppose we have two programs. c2. we might say that the running time grows “on the order of” n3.g.000. then almost any algorithm is fast enough. but fo r your value of n. optimizations in compilation. Let us consider how to make this idea mathematically formal. Therefore.6 days 1 sec 1. But it is important to understand these assumptions and the limitations of asymptotic anal ysis.(but not all) cases. we define (g(n)) to be a set of functions: (g(n)) = ff(n) j there exist strictly positive constants c1. (The latter algorithm may be faster because it uses a more sophisticated and com plex algorithm. etc). so we will not need to worry about these issue s.000 10. the 13n3 term dominates the others. and the added sophistication results in a larger constant factor.. For example. the asymptotically larger value is fine. n 10) th e first algorithm is the faster of the two. These assumptions are not always reasonable. People are most concerned about running times for large inputs. n T1(n) T2(n) T1(n)=T2(n) 10 0.

Let’s see why the formal definition bears out this informal observation.” Consider the following (almost correct) reasoning: f(n) = 8n2 + 2n−3 8n2 −3 = 7n2 + (n2 −3) 7n2 = 7n2: Thus. So. Our informal rule of keepin g the largest term and throwing away the constants suggests that f(n) 2 (n2) (since f grows quadraticall y). if n p 3. we have n0 p 3 and from the upper bound we have n0 1.asymptotically equivalent. The po rtion of the definition that allows us to select c1 and c2 is essentially saying “the constants do not matter b ecause you may pick c1 and c2 however you like to satisfy these conditions. if we set c1 = 7. This means that they have essentially the same growth rates for large n. for all n n0. and second. since you only have to sati sfy the condition for all n bigger than n0. they all grow quadratically in n. From the lower bound. Lower bound: f(n) grows asymptotically at least as fast as n2: This is establish ed by the portion of the definition that reads: (paraphrasing): “there exist positive constants c1 and n0. but it is true for all n 1. (n2=5 + p n−10 log n).” Consider the following reasoning (which is almost correct): f(n) = 8n2 + 2n−3 8n2 + 2n 8n2 + 2n2 = 10n2: This means that if we let c2 = 10. For example. that f(n) grows no faster asymptotically than n2. then both are true. such that f(n) c2n2 for all n n0. which is what we need. since as n becomes large.” The portion of the definition th at allows us to select n0 is essentially saying “we are only interested in large n. This is not true for all n. which is what we need. but they are tru e for all sufficiently large n. such that f(n) c1n2 for all n n0. We need to show two things: first. Thus. then we are done. the dom inant (fastest growing) term is some constant times n2. and you may make n0 as big a constant as you like. We have implicitly made the assumption that 2n 2n2. But in the above reasoning we have imp licitly made the assumptions that 2n 0 and n2 − 3 0. that f(n) does grows asymptotically at least as fast as n2. (8n2 + 2n−3). functions such as 4n2. So let us select n0 = p 3. Upper bound: f(n) grows asymptotically no faster than n2: This is established by the portion of the definition that reads “there exist positive constants c2 and n0. if we let c1 = 7. c2 = 10. These are not true for all n. and now we have f(n) c2n2 for all n n0. and n0 = p 3. let us selec t n0 = 1. then we are done. in conclusion.” An example: Consider the function f(n) = 8n2 + 2n − 3. then . and so combining these we let n0 be the larger of the two: n0 = p 3. and now we have f(n) c1n2. and n(n − 3) are all intuitively asymptotically equivalent. In particular. In other words. We’ll do both very carefully.

we have established that f(n) 2 n2. If we divide both side by n we have: lim n!1 8n + 2− 3 n c2: It is easy to see that in the limit the left side tends to 1. To show this formally. we know that as n becomes large enough f(n) = 8n2+2n−3 will eventually exceed c2n no matter Lecture Notes 92 CMSC 451 how large we make c2 (since f(n) is growing quadratically and c2n is only growin g linearly). Here the idea will be to violate the lower bound: “ther e exist positive constants c1 and n0. and this is exactly what the definition requires. If we divide b oth side by n3 we have: lim n!1 8 n + 2 n2 − 3 n3 c1: It is easy to see that in the limit the left side tends to 0. suppose towards a contradiction that constants c2 and n0 did exist. and eventually any cubic function will exceed it. Since this is true for all sufficiently large n then it must be true i n the limit as n tends to infinity. then we would have to satisfy both the upper and lower bounds. Since this is true for all sufficiently large n then it must be true in the limit as n tends to infinity. such that f(n ) c2n for all n n0. This means that f(n) =2 (n). su ch that 8n2 + 2n−3 c2n for all n n0. First. let’s show tha t f(n) =2 (n). c2.” Informally. such that f(n) c1n3 for all n n0.we have 0 c1g(n) f(n) c2g(n) for all n n0.) Now let’s show why f(n) is not in some other asymptotic class. (Whew! That was a lot more w ork than just the informal notion of throwing away constants and keeping the largest term. this statement is violated. Let’s show that f(n) =2 (n3). and n0. such that 8n2+2n−3 c1n3 for all n n0. To show this formally. In particular. But the upper bound i s false. and so the only wa . suppose towards a contradiction that constants c1 and n0 did exist. but it shows how this informal notion is implemented formally in the definition.” Informally this is true because f(n) is growing quadratically. the upper bound requires us to show “there exist positive constants c2 and n0. and so no matter h ow large c2 is. Since we have shown (by constr uction) the existence of constants c1. It turns ou t that the lower bound is satisfied (because f(n) grows at least as fast asymptotically as n). If this were true.

The Limit Rule for : The previous examples which used limits suggest alternative way of showing that f(n) 2 (g(n)). Whereas. Sometimes we are only interested in proving one bound or the o ther. Limit Rule for -notation: Given positive functions f(n) and g(n). Intuitively. f(n) 2 O(g(n)) means that f(n) grows asymptotically at the same rate or faster than g(n). Definition: Given any function g(n). for some constant c 0 (nonnegative but not infinite). (g(n)) = ff(n) j there exist positive constants c and n0 such that 0 cg(n) f(n) for all n n0g: Compare this with the definition of . and -notation only enforces the lower bound. O(g(n)) = ff(n) j there exist positive constants c and n0 such that 0 f(n) cg(n) for all n n0g: Definition: Given any function g(n). For example f(n) = 3n2 + 4n 2 (n2) but it is not in (n) or (n3). Lecture Notes 93 CMSC 451 Limit Rule for O-notation: Given positive functions f(n) and g(n). if lim n!1 f(n) g(n) 6= 0 (either a strictly positive constant or infinity) then f(n) 2 (g(n)). then f(n) 2 O(g(n)). if lim n!1 f(n) g(n) = c. O-notation and -notation: We have seen that the definition of -notation relies on proving both a lower and upper asymptotic bound. Finally. The O-notation allows us to state asymptotic upper bounds and the -notation allows us to state asymptotic lower bounds. Also observe that f(n) 2 (g(n)) if and o nly if f(n) 2 O(g(n)) and f(n) 2 (g(n)). f(n) 2 O(g(n)) means that f(n) grows asymptotically at the same rate or slower than g(n). You will see that O-notation only enforces the upper bound of the definition. Limit Rule for -notation: Given positive functions f(n) and g(n). then f(n) 2 (g(n)). But f(n) 2 O(n2) a nd in O(n3) but not in O(n). This limit rule can be applied in almost every instance (that I know of) where t . if lim n!1 f(n) g(n) = c. but by hypothesis c1 is positive. f(n) 2 (n2) and in (n) but not in (n3). for some constant c > 0 (strictly positive but not infinity).y to satisfy this requirement is to set c1 = 0. This means that f(n) =2 (n3).

and then applying L’Hˆopital’s rule. But since mos t running times are fairly well-behaved functions this is rarely a problem. where f0(n) and g0(n) denote the derivatives of f and g relative to n. One important rule to remember is the following: L’Hˆopital’s rule: If f(n) and g(n) both approach 0 or both approach1in the limit. The only exc eptions that I know of are strange instances where the limit does not exist (e. and it is almost always easier to apply than the formal definition. it follows that f(n) 2 (g(n)). For example. Exponentials and Logarithms: Exponentials and logarithms are very important in a nalyzing algorithms.he formal definition can be used. For example: n500 2 O(2n): For this reason. the n lim n!1 f(n) g(n) = lim n!1 f0(n) g0(n) .. Lemma: Given any positive constants a > 1. The following are nice to keep in mind.g.g. f(n) = n(1+sin n)). we will try to avoid exponential running times at all costs. the limit of a finit e sum is the sum of the individual limits). (If not. Co nversely. dredge out your calculus book to remember. recall the function f(n) = 8n2 + 2n − 3. To show that f(n) 2 (n2) we l et g(n) = n2 and compute the limit. Since 8 is a nonzero co nstant.) Most of the rules are pretty self evident (e. The terminology lgb n means (lg n)b. The important bottom line is that polynomials always grow more slowly than expon entials whose base is greater than 1. For example: lg500 n 2 O(n): Lecture Notes 94 CMSC 451 . We have lim n!1 8n2 + 2n−3 n2 = lim n!18 + 2 n − 3 n2 = 8. You may recall the important rules from calculus for evaluating limits. (since the two fractional terms tend to 0 in the limit). and c: lim n!1 nb an = 0 lim n!1 lgb n nc = 0: We won’t prove these. logarithmic powers (sometimes called polylogarithmic functions) grow more slowly than any polynomia l. but they can be shown by taking appropriate powers. b.

or (2) you know that this is a worst-case run ning time that will rarely occur in practical instances. (E. n 20). given that you need (n) time just to read in all the data. For example. Although the second algorithm is twice as fast for large n (because of the 1=2 factor multiplying th e n2 term).g. (n2). if it means avoiding any additional powers of n. Are their even bigger functions? Definitely! For example.g. by my calculations. here is a little list. Supplemental Lecture 2: Max Dominance Read: Review Chapters 1–4 in CLRS. Max Dominance Revisited: Returning to our Max Dominance algorithms. Since many p roblems require sorting the inputs.: Polynomial time. Asymptotic Intuition: To get a intuitive feeling for what common asymptotic runn ing times map into in terms of practical usage. 000). (3n): Exponential time. n 1. For example lg2 n n for all n 16. look up the definition of Ackerman’s function in our text. (n): This is about the fastest that an algorithm can run. which ope . it should be mentioned that these last observations are really as ymptotic results.g. lg500 n n only for n > 26000 (which is much larger than input size you’ll ever see). (1): Constant time. Thus. if you want to see a f unction that grows inconceivably fast.. They are true in the limit for large n. So far we have introduced a simple brute-force algorithm that ran in O(n2) time. Faster Algorithm for Max-Dominance: Recall the max-dominance problem from the la st two lectures. this is still considered quite efficient. (n log n): This is the running time of the best sorting algorithms. we will usually be happy to allow any number of additional loga rithmic factors.) Also it is the time to find an obj ect in a sorted list of length n by binary search. In case (2). At this point. n 50). : : :. this applies to all reasonably large input sizes. Expand ing the latter function and grouping terms in order of their growth rate we have T2(n) = n2 2 +nlog n − n 2 : We will leave it as an easy exercise to show that both T1(n) and T2(n) are (n2). (nn): Acceptable only for really small inputs (e. inserting a key into a balanced binary tree. this does not represent a significant improvement.For this reason. (n3). you can’t beat it! (log n): This is typically the speed that most efficient data structures operate in for a single access. for small powers of logarithms. This is only acceptable when either (1) your know t hat you inputs will be of very small size (e. you should take this with a grain of salt. but you should be careful just how high the crossover point is. it would be a good idea to try to get a more accurate average case analysis. But. These running times are acceptable either wh en the exponent is small or when the data size is not too large (e. (n!). recall that one had a running time of T1(n) = n2 and the other had a running time of T2(n) = nlog n + n(n − 1)=2.g. (2n).

ignoring constant factors: n2 n lg n = n lg n : (I use the notation lg n to denote the logarithm base 2.rated by comparing all pairs of points. output P[n]. both algorithms are proba . We keep track of the index j of the most recently seen maximal point. (Initially the rightmost point is maximal.) For relatively small values of n (e. This suggests. so inside of O-notation. // yes. it is maximal if and only if P[i]:y P[j]:y.g. The question we consider today is whether there is an approach that is significantly better. let’s look at the rati o of the running times. n] had the maximum y-coordinate. ln n to denote the natu ral logarithm (base e) and log n when I do not care about the base. Max Dominance: Sort and Reverse Scan MaxDom3(P. n) { Sort P in ascending order by x-coordinate. : : : . For any set of points. and the code inside takes constant time. This suggests th at we can sweep the points backwards. This suggests the following algorithm. even thoug h we have cut the number of comparisons roughly in half.. and then compared each point against the subsequent points in the sorted order. only improved matters by a constant factor. from right to left. Last time we considered a slight improvement. Note that a change in base only affects the v alue of a logarithm function by a constant amount. for i = n-1 downto 1 { if (P[i]. // last point is always maximal j = n. we will usually just write log n. How much of an improvement is this? Probably the most accurate way to find out w ould be to code the two up. and compare their running times.) When we encounter the point P[i]. less than 100). because there is just a sing le loop that is executed n − 1 times.y >= P[j].y) { // is P[i] maximal? output P[i]. // P[i] has the largest y so far } } } The running time of the for-loop is obviously O(n). the poi nt with the maximum ycoordinate is the maximal point with the smallest x-coordiante. we could just test against that point. which sorted the points by their x-coordinate. for a total of O(n log n) time. Howe ver. Can we save time by making only one comparison for each point? The inner while loop is testing to see whether an y point that follows P[i] in the sorted list has a larger y-coordinate. each point is still making lots of comparisons. that if we knew which poin t among P[i + 1. this improvement. But just to get a feeling. Lecture Notes 95 CMSC 451 A Major Improvement: The problem with the previous algorithm is that.output it j = i. The total running time is domina ted by the O(n log n) sorting time. How can we do this? Here is a simple observation.

10. We will talk more about these methods as the semester continues. Divide and Conquer Approach: One problem with the previous algorithm is that it relies on sorting. Of course. irrespective of the constant factors. The key ingredient is a function that takes the maxima of two sets. This will not be guaranteed to split the list into two equal parts. 000=20 = 50. // one point is trivially maximal m = n/2. We will describe the algorithm at a very high level. One of the basic maxims of algorithm design is to first approach any problem usi ng one of the standard algorithm design paradigms. What is this paradigm? Lecture Notes 96 CMSC 451 Divide: Divide the problem into two subproblems (ideally of approximately equal sizes). M2). Let’s consider the first method.) On larger inputs. // solve for second half return MaxMerge(M1. 000. say.n]. How shall we divide the problem? I can think of a couple of ways. The input will be a point array. and a point array will be returned.bly running fast enough that the difference will be practically negligible. For even larger inputs. This is quite a significant difference. and split into two subarrays of equal siz e P[1::n=2] and P[n=2 + 1::n]. 000. (Rule 1 of algorithm optimization: Do n’t optimize code that is already fast enough. there is no particular relationship between t he points in one side of the list from the other. 000.. depth-first search. This is nice and clean (since it is usually easy to get good code for sorting without troubli ng yourself to write your own). Another approach. 000. say.m]. e. where r is a random integer in the range from 1 to n. we would need to factor in constant fact ors. However. those elements whose x-coordinates are less than or equal to x and those that gr eater than x. and then partition the list into two sublists. it is hard to imagine that the constant fact ors will differ by more than. but leads t o a tougher analysis. Just take the array of points P[1::n]. we are looking at a ratio of r oughly 1. (The quicksort method will also work. m). One is similar to how MergeSort operates.g. which is more reminiscent of QuickSort is to select a random e lement from the list.. so there is a 100to-1 ratio in running times. and Combine: Combine the solutions to the two subproblems into a global solution. but since we are not using any really complex data structures.) Here is more concrete outline. if you really wanted to squeeze the most efficiency out of your code. y ou might consider whether you can solve this problem without invoking a sorting algorithm. Conquer: Solve each subproblem recursively. x = P[r]. For this problem. the ratio of n to log n is abou t 1000=10 = 100. n) { if (n == 1) return {P[1]}. divide and conquer. n = 1. and merges them into an overall set of maxima. greedy algorithm s. dynamic programming. divide-and-conquer is a natural method to choose. n-m). Max Dominance: Divide-and-Conquer MaxDom4(P. n = 1. called a pivot. // merge the results . // midpoint of list M1 = MaxDom4(P[1. say. 000. but on average it can be show n that it does a pretty good job. Because we do not sort the points. // solve for first half M2 = MaxDom4(P[m+1.

11) (11.5) 2 4 6 8 10 2 4 6 8 10 12 14 16 12 (14.4) (7. The details will be left as an exercise.10) 2 4 6 8 10 2 4 6 8 . 10) in the example. Observe that if a point is to be maximal overall. then this point is maximal .14) (16. th at is. T(n) = 2T(n=2) + n if n > 1. In either case. just because a point is maximal in some list. (Consider point (7. giving: T(n) = 1 if n = 1. The main question is how the procedure Max Merge() is implemented. does not imply that it is globally maxi mal.) However. then the best way is usually by setting up a recurrence. Otherwise it is not copied. and is copied to the next position of the result list. because it do es all the work. Let us assume that it returns a list of points in sorted order according to x-coordinat es of the maximal points. if it dominates all the points of the other sublist. If its y-coordinate is larger than the y-coordinate of the point under the other finger.} The general process is illustrated below. The result list is returned. We will ignore constan t factors. Observe that because we spend a constan t amount of time processing each point (either copying it to the result list or skipping over it) the total execu tion time of this procedure is O(n). a function which is defined recursively in terms of itself. and the additional overhead of merging the solutions is O(n). then it must be maximal in one of the two sublists. Take the finger pointing to the point with the smaller x-coordinate. However. and repeat the process. It maintains two pointers. then we can assert that it is maximal. Think of these as fingers.7) (4. Recurrences: How do we analyze recursive procedures like this one? If there is a simple pattern to the sizes of the recursive calls. writing O(n) just as n. I will describe the procedure at a very high level. We break the problem into two subproblems of size roughly n=2 (we will say exact ly n=2 for simplicity). we move to the n ext point in the same list.3) (2. It operates by walking throu gh each of the two sorted lists of maximal points. one pointing to the next unprocessed item in each list. Lecture Notes 97 CMSC 451 (13.

10) (15.12) (14. See CLRS for the more complete version of the Master Theorem and its proof. The easiest method is to apply th e Master Theorem that is given in CLRS. Solutions to subproblems.4) (7.7) (4. Here is a slightly more restrictive version. Case (1): a > bk then T(n) is (nlogb a).10 12 14 16 12 14 (5.4) (7.10) (15. Theorem: (Simplified Master Theorem) Let a 1. Case (3): a < bk then T(n) is (nk).1) (7.3) (2. 68: Divide and conquer approach. defined for n 0.14) (16.13) (12.5) (9. Lecture Notes 98 CMSC 451 Solving Recurrences by The Master Theorem: There are a number of methods for sol ving the sort of recurrences that show up in divide-and-conquer algorithms. b > 1 be constants and let T(n) be the recurrence T(n) = aT(n=b) + cnk.7) (13. Case (2): a = bk then T(n) is (nk log n).10) 14 4 (5. Merged solution.10) (9.3) (2.1) (12.11) (11.12) (15.12) (14.14) (16.7) (13.13) 6 8 10 12 14 16 12 14 (5. but adequate for a lot of instances. .10) 2 4 6 8 10 2 Fig.7) (7.1) (7.5) Input and initial partition.13) (12.7) (4.11) (11. (9.

and k = 1. There many recurrences that cannot be put into this form. b = 2. T(n) = 2T n 3 +n = 2 2T n 9 +n 3 +n = 4T n 9 + n+ 2n 3 = 4 2T n 27 + n 9 + . This pattern usually results in a summation that is easy to sol ve. until seeing the general patter n emerge. it is actually based on expansion. other met hods are needed. This is a rather painstaking process of repeatedly applying the definition of the recurr ence until (hopefully) a simple pattern emerges.) For such recurrences. For example. This solves to T(n) = (nlog2 n). T(1) = 1 T(n) = 2T n 3 +n if n > 1 First we expand the recurrence into a summation. but the Master Theorem (either this form or the one in CLRS will not tell you this.Using this version of the Master Theorem we can see that in our recurrence a = 2 . the follo wing recurrence is quite common: T(n) = 2T(n=2) + n log n. so a = bk and case (2) applies. Let us consider applying this to the following recurrence. We assume that n is a power of 3. Thus T(n) is (n log n). Expansion: A more basic method for solving recurrences is that of expansion (whi ch CLRS calls iteration). If you look at the proof in CLRS for the Master Theorem.

and so it is (n).n + 2n 3 = 8T n 27 + n + 2n 3 + 4n 9 . = 2 k T n 3k + kX−1 i=0 2in 3i = 2kT n 3k +n kX−1 i=0 (2=3)i: The parameter k is the number of expansions (not to be confused with the value o f k we introduced earlier on the overhead). Substituting this in and using the identity alog b = blog a we have: T(n) = 2log3 nT(1) + n logX3 n−1 i=0 (2=3)i = nlog3 2 + n logX3 n−1 i=0 (2=3)i: Lecture Notes 99 CMSC 451 Next. We want to know how many expansions are needed to arrive at the b asis case. T(n) is dominated by the 3n term asymptotically.. we can apply the formula for the geometric series and simplify to get: T(n) = nlog3 2 + n 1 − (2=3)log3 n 1 − (2=3) = nlog3 2 + 3n(1 − (2=3)log3 n) = nlog3 2 + 3n(1 − nlog3(2=3)) = nlog3 2 + 3n(1 − n(log3 2)−1) = nlog3 2 + 3n−3nlog3 2 = 3n−2nlog3 2: Since log3 2 0:631 < 1. To do this we set n=(3k) = 1.. meaning that k = log3 n. .

To c onstruct a minimum-sized AVL tree of height i. L(i) = L(i−1) + L(i − 2). from which we have Fn n−2 + n−3 = n−3(1 + ): Lecture Notes 100 CMSC 451 We want to show that this is at most n−1 (for a suitable choice of ). you will observe that Fn appears to grow exponentially. where 1 < < 2. We can use induction to prove this and derive a bound on . and then attempt to verify its correctness through induction. 69: Minimum-sized AVL trees.Induction and Constructive Induction: Another technique for solving recurrences (and this works for summations as well) is to guess the solution. you create a root node whose children consist of a minimum -sized AVL tree of heights i − 1 and i − 2. implying that we w ant to find the roots of the equation 2 − − 1 = 0: By the quadratic formula we have = 1 p 1 + 4 2 = 1 p . Lemma: For all integers n 1. whenever n 2. that of the Fibonacci numbers. 1 < < 2. Fn n−1 for some constant .) At the critical value of this inequality will be an equality. The Fibonacci numbers arise in data structure design. you will learn that the minimum-sized AVL trees are produced by the recursive co nstruction given below. but not as fast as 2n. It is tempting to conjecture that Fn n−1. we can apply the induction hypothesis. Induction step: For the induction step. In the course of the induction proof. Sometimes there are parameters whose values you do not know. Using this induction hypothesis we will show that the lemma holds for n itself. If you expand the Fibonacci series for a number of terms. Since n 2. If you study AVL (height b alanced) trees in data structures. you will usually find out what these values must be. This is not true for all values of (for example it is not true w hen = 1 but it is true when = 2. It is easy to see that L(i) = Fi+1. Basis: For the basis cases we consider n = 1. Let L(i) denote the number of leaves in the minimum-sized AVL tree of height i. Observe that F1 = 1 0. L(0) = 1 L(1)=1 L(2)=2 L(3)=3 L(4)=5 Fig. We will consider a famous example. for some real para meter . Proof: We will try to derive the tightest bound we can on the value of . This is fine. let us assume that Fm m−1 whenever 1 m < n. Thus the number of leaves obeys L(0) = L(1) = 1. we have Fn = Fn−1 +Fn−2. since n − 1 and n − 2 are both strictly less th an n. Clearly this w ill be true if and only if (1 + ) 2. Now. or the general form of the solution. as desired. F0 = 0 F1 = 1 Fn = Fn−1+Fn−2 for n 2.

and hence would not be a poss ible candidate for . Let us consider an approach to determine an exact representation of Fn. By the way. and we had to generate a good guess before we were even abl e to start. a1. but we actually determined the value of which makes the lemma true. Knuth. and hence cannot be applied to F0! To fix it we could include F2 as part of the basis case as well. but we did not get an exact answer. Notice not only did we prove the lemma by induction. we could define a polynomial function such that these are the coefficients of the function: G(z) = a0 +a1z +a2z2 +a3z3 +: : : This is called the generating function of the sequence. The Art of Computer Programming. Here we claim that F2 = F1 + F0 and then we apply the induction hypothesis to both F1 and F0. We will (almost) never assign it a specific value. But the induction hypothesis only applies for m 1. There a good description of generatin g functions in D. Thus. Supplemental Lecture 3: Recurrences and Generating Functions Read: This material is not covered in CLR. Generating Functions: The method of constructive induction provided a way to get a bound on Fn. architecture and art. and vice versa. every infinite sequence of numbers has a corresponding generating function. observe that one of the roots is negative. a2. Can you spot it? The error oc curs in the case n = 2. Conside r any infinite sequence: a0. the value = 1 2 (1+ p 5) is a famous constant in mathematics. a3. This proportio n occurs throughout the world of art and architecture. which re quires no guesswork. Vol 1. Two numbers A and B satisfy the golden ratio if A B = A + B A : It is easy to verify that A = and B = 1 satisfies this condition. It is the golden ratio. called a generating function. The positive root is = 1 + p 5 2 1:618: There is a very subtle bug in the preceding proof. : : : If we would like to “encode” this sequence succinctly. This method is based on a very elegant concept. What is the advantage of this representation? It turns out that we can perform arithmetic Lecture Notes 101 CMSC 451 . E. What is z? It is just a symbolic variable.5 2 : Since p 5 2:24. This is why this method is called constructive induction.

transformations on these functions (e. multiplying them. (The particular manipulation we picked was chosen to cause this cancellation to occur. a2. 1=(1−z) is the generating function for the sequence (1. notice that if we multiply the generating function by a factor of z. : : :). since then we could then extract the coefficients of the power . For example. 1. Let’s consider the generating function for the Fibonacci numbers: G(z) = F0+F1z+F2z2+F3z3+: : : = z +z2 + 2z3 + 3z4 + 5z5 +: : : The trick in dealing with generating functions is to figure out how various mani pulations of the generating function to generate algebraically equivalent forms. as the coefficients of this function if expanded as a power series.) From this we may conc lude that G(z) = z 1−z −z2 : So. : : :). In general. The first is to observe that there are some functions for which it is very easy to get an power series expansion. If 0 < c < 1 then 1X i=0 ci = 1 1 − c : Setting z = c. a. we have 1 1−z = 1+z +z2 +z3 +: : : (In other words. It would be great if we co uld modify our generating function to be in the form of 1=(1 − az) for some constant a. For example.. let’s try the following manipulation. adding them. Compute G(z) − zG(z) − z2G(z). this has the effect of shifting the sequence to the r ight: G(z) = F0 + F1z + F2z2 + F3z3 + F4z4 + : : : zG(z) = F0z + F1z2 + F2z3 + F3z4 + : : : z2G(z) = F0z2 + F1z3 + F2z4 + : : : Now. It turns out that some n icely-structured sequences (like the Fibonacci numbers. a3. differe ntiating them) and this has a corresponding effect on the underlying transformations. now we have an alternative representation for the Fibonacci numbers. So what good is this? The main goal is to get at the coefficients of its power series expansion. and see what we get (1 − z − z2)G(z) = F0+ (F1 −F0)z + (F2 −F1 −F0)z2 + (F3 −F2 −F1)z3 +: : : + (Fi −Fi−1 −Fi−2)zi +: : : = z: Observe that every term except the second is equal to zero by the definition of Fi.g. 1. and many sequences arising from linear recurrences) have generating functions that are easy to write down and manipulate. given an constant a we have 1 1 − az = 1+az + a2z2 + a3z3 + : : : is the generating function for (1. There are certain common tricks that people use to manipulate generat ing functions. the following is a simple consequence of the formula for the geomet ric series.

In general. Lecture Notes 102 CMSC 451 for some A. we would like to rewrite the generating function in the fol lowing form: G(z) = z 1−z−z2 = A 1−az + B 1 − bz . We can then solve for a and b by taking the reciprocals of the roots of this quadratic. In order to do this. A similar trick can be applied to get B. a. Then by some simple algebra we can p lug these values in and solve for A and B yielding: G(z) = z 1−z−z2 = 1= p 5 1−z + −1= p 5 1 − ^ ! = 1 p 5 1 1 − z − 1 1 − ^ . b. multiply the equation by 1 − z. to determine A. because we can extract the coefficients for these two fractions from the above function. (In particular.series easily. From this we have the following: G(z) = 1p 5 ( 1 + z + 2z2 + : : : −1 + −^z + −^2z2 + : : : ) Combining terms we have G(z) = 1 p 5 1X . this is called the method of partial fractions.) Now we are in good shape.B. where = (1+ p 5)=2 and ^ = (1− p 5)=2. but it is not hard to verify the roots of (1−az)(1−bz) (which are 1=a and 1=b) must be equal to the roots of 1 − z − z2. We will skip the steps in doing this. and then consider what happens when z = 1=.

and (2) applyi ng the method of partial fractions to get the generating function into one for which we could easily read off the f inal coefficients. The problem that we will consider is very easy to state. Thus. but surprisingly diffic ult to solve optimally. it is often desirable to parti tion a set about its median value. into two sets of roughly equal size. we will make the simplifying assumption that all the elements are distinct for now. We will def ine the median to be either of these elements. when you observe that ^ < 1. Define the rank of an element to be one p lus the number of elements that are smaller than this element. namely the elements of ranks n=2 and (n=2) + 1. for large enough n. Selection: We have discussed recurrences and the divide-and-conquer method of so lving problems. You might try this for a few specific values of n to se e why this is true. Since duplicate elements make our life more complex (by creating multiple elements of the same rank). since in divide-and-conquer applications. Today we will focus on the following genera . Today we will give a rather surprising (and very tricky) algorithm which shows the power of th ese techniques. By the way. This is a rather remarkable. Thus we have. because it says that we can express the integer Fn as the sum of two powers of to irrational numbers and ^. It will be easy to get around this assumption later. They are also useful. Suppose that you are given a set of n numbers. rounded to the nearest integer. The only parts that involv ed some cleverness (beyond the invention of generating functions) was (1) coming up with the simple closed form formula for G(z) by taking appropriate differences and applying the rule for the recurrence. If n is odd then the median is defined to be the element of rank (n + 1)=2. Of particular interest in statistics is the median. For example. The minimum is of rank 1 and the maximum is of rank n. the median income in a community is likely to be mor e meaningful measure of the central tendency than the average is. the rank of an elemen t is its final position if the set is sorted. In Lecture Notes 103 CMSC 451 statistics it is common to return the average of these two elements. In particular it follows that Fn = 1 p 5 (n − ^n): This is an exact result.i=0 (i − ^i)zi: We can now read off the coefficients easily. Medians are useful as measures of the central tendency of a set. and no guesswork was needed. it is clear that the first term is the dominant one. especially when the distribution of values is highly skewed. Fn = n= p 5. whereas it cannot have a significant influen ce on the median. Supplemental Lecture 4: Medians and Selection Read: Chapter 9 of CLRS. When n is even there are two natural choices. since if Bill Gates lives in your comm unity then his gigantic income may significantly bias the average.

simply by sorting t he numbers of A. where the number of subproblems is just 1.lization. Selection: Given a set A of n distinct numbers and an integer k. 1 k n. In particul ar. is it possible to solve this problem in (n) time? We will see that the answer is yes. Then we sol ve the problem recursively on whatever items remain. called the selection problem. Here . which we will denote by x. This is illustrated below. The Sieve Technique: The reason for introducing this algorithm is that it illust rates a very important special case of divide-and-conquer. Each of the resulting recursive solutions then do the sam e thing. and we want to find the kth smallest item (where k r − p + 1). we fin d that we do not know what the desired item is. output t he element of A of rank k. We do not know which item is of intere st. Recall that we are given an array A[1::n] and an integer k. The initial call will be to the entire array A[1::n]. which I call the sieve technique. In this latter case we have eliminated q smaller elements. If k = xRank. then the pivot is the kth smallest. but we can identify a large enough number of elements that cannot be the desired value. then we know that we need to recursively search in A[p::q−1] and ifk > xRank then we need to recursively search A[q+1::r]. let us apply it to the selection problem. the items may appear in any order. We think of divide-and-con quer as breaking the problem into a small number of smaller subproblems. The question is whether it is possible to do better. We then partition A into three parts. 0:0001n). If k < xRank. T he sieve technique is a special case. called the pivot element. Let xRank = q − p+1. and the solution is far from obvious. but for now just think of it as a random element of A. A[q] contains the element x. which are then solved recursively. subarray A[p::q − 1] will contain all th e elements that are less than x. There are two principal algorithms for solving the selection problem. however after doing some amount of analysis of the data. and can be eliminated from further consideration. It applies to problems where we are interested in finding a single item from a larger set of n items. for some constant k. and then returning A[k]. and A[q+1::r]. so we want to find the element of rank k − q. Applying the Sieve to Selection: To see more concretely how the sieve technique works. (Recall tha t we assumed that all the elements are distinct. In particular “large enough” means tha t the number of items is at least some fixed constant fraction of n (e. we will assume th at we are given a subarray A[p::r] as we did in MergeSort. n=2. and we may just return it. Since the algorithm will be applied inductively. n=3. The sieve technique works in phases as follows. It is easy to see that the rank of the pivot x is q − p+1 in A[p::r]. and want to find the k-th smallest element of A. but they d iffer only in one step. The selection problem can easily be solved in (n log n) time. eliminating a constant fraction of the remaining set.) Within each subarray. Later we will see how to choose x. taking say (nk) time. will contain all the element that are greater than x. which involves judiciously choosing an item from the array.g.

The question that remains is how many elements did we succeed in elimin ating? If x is the largest Lecture Notes 104 CMSC 451 Before partitioing After partitioing 9 2 6 4 1 3 7 pivot 3 1 4 6 9 5 x p r p q r A[q+1. Notice that this algorithm satisfies the basic form of a sieve algorithm. Otherwise we either eliminate the pi vot and the right subarray or the pivot and the left subarray.is the complete pseudocode. but as sume for now that they both take (n) time.q−1] < x 5 2 7 Partition (pivot = 4) 9 7 5 6 (k=6−4=2) Recurse x_rnk=2 (DONE!) 6 5 5 6 (pivot = 6) Partition (k=2) Recurse x_rnk=3 (pivot = 7) Partition (k=6) Initial x_rnk=4 6 7 3 1 4 6 2 9 5 4 1 9 . and recur ses on the rest.r] > x A[p... It ana lyzes the data (by choosing the pivot element and partitioning) and it eliminates some part of the data set. When k = xRank then we get lucky and eliminate everything. We will discuss the details of choosing the pivot and partitioning later.

x..r]> xRank = q .5 3 7 2 6 9 5 7 Fig. A[q+1. r. If we e xpand this recurrence level by level we see that we get the summation T(n) = n+ n 2 + n 4 + 1X i=0 n 2i = n 1X i=0 1 2i : Recall the formula for the infinite geometric series. r) // choose the pivot element q = Partition(A. T(n) = 1 if n = 1. return it else { x = ChoosePivot(A. k) // select from left subarray else return Select(A. T(n=2) + n otherwise.q-1]. This would lead to the following recurrence. 70: Selection Algorithm. Selection by the Sieve Technique Select(array A. p. p. q-1. r. q+1.r] if (p == r) return A[p] // only 1 item left. then we get int o trouble. meaning that we r ecurse on the remaining n=2 elements. Ideally x should have a rank that is neither too large nor too small. Using . int r. Let us suppose for now (optimistically) that we are able to design the procedure Choose Pivot in such a way that is eliminates exactly half the array with each phase. In fact. because we may only eliminate it and the few smaller or larger elements of A.. For any c such that jcj < 1. int p. x) // partition <A[p. then we may only succeed in eliminating one el ement with each phase. int k) { // return kth smallest of A[p. P1 i=0 ci = 1=(1 − c).p + 1 // rank of the pivot if (k == xRank) return x // the pivot is the kth smallest else if (k < xRank) return Select(A.. k-xRank)// select from right subarray } } Lecture Notes 105 CMSC 451 or smallest element in the array. p. if x is one of the smallest elements of A or one of the largest. We can solve this either by expansion (iteration) or the Master Theorem.

Note that the assumption of eliminating half was not critical. let’s concentrate on how to choose the pivot. and we would have gotten a geo metric series involving 99=100. then the recurrence would have been T(n) = T(99n=100) + n. However. Otherwise. we are i n trouble if q is very small. If we could select q so that it is roughly of middle rank. In this algorithm we make many passes (it could be as many as lg n). then we may have to recurse on the right subarray of size n−q. The partitioning algorithm will split the arra y into A[1::q − 1] < x. In either case. A[q] = x and A[q + 1::n] > x. k will be chosen so that we have to r ecurse on the larger of the two subarrays. then we may have to recurse on the left subarray of size q −1. and the second is how to partition the array.this we have T(n) 2n 2 O(n): (This only proves the upper bound on the running time. Both need to be solved in (n) time. we will disc uss partitioning in detail. we get this convergent geometric series in the analysis. The reason is that Lecture Notes 106 CMSC 451 roughly half of the elements lie between ranks n=4 and 3n=4.) This is a bit counterintuitive. implying a convergent series. If k = q. Later. Let’s see why. and if q < n=2. but it is easy to see tha t it takes at least (n) time. The key is that we want the procedure to eliminate at least some constant fracti on of the array after each partitioning step. For the rest of the lecture. which is still less than 1. or if q is very large. Normally you would think that in order to design a (n) time algorithm you could only make a single. The first is how to choose the pivot element. then the larger subarray will never be larger than 3n=4. when we are given A[1::n]. respectively. then we will be in go od shape. which shows that the total running time is indeed linear in n. so in the worst case. For example. If we eliminated even one per cent. then we are done. if n=4 q 3n=4. This lesson is well worth remembering. when we discuss QuickSort. Choosing the Pivot: There are two issues that we have left unresolved. so picking a random element as the pivot will . Thus if q > n=2. Suppose that the pivot x turns out to be of rank q in the array. or perhaps a constant number of passes over the data set. Let’s consider the top of the recurrence. because we eliminate a constant f raction of elements with each phase. Actually this works pretty well in practice. Earlier we said that we might think of the pivot as a random element of the array A. Eliminating an y constant fraction would have been good enough. we need to search on e of the two subarrays. It is often possible to achi eve running times in ways that you would not expect. so the total running time is (n). They are of sizes q − 1 and n − q. Actually this is not such a bad ide a. The subarray that contains the kth small est element will generally depend on what k is. The second problem is a rather easy programming exercise. Recall that before we said that we might think of the pivot as a random element of A.

we need to argue that x satisfies the desired rank properties. For example. There will be m group medi ans. e. we will ha ve to call the selection algorithm recursively on B. 1. 8 10 27 Group 29 11 58 39 60 55 1 21 52 19 48 63 12 23 3 24 37 57 14 6 24 48 57 14 25 30 . Median of medians: Compute the median of the group medians. etc. k).g. Each will take (1) time. A[1::5]. Return x as the desired pivot. A[6::10]. Of course. Here is the description for Select Pivot: Groups of 5: Partition A into groups of 5 elements. Group medians: Compute the median of each group of 5.g. A[11 ::15]. For this. We will have to describe this algorithm at a ver y high level. and k = b( m + 1)=2c. since the details are rather involved.succeed about half the time to eliminate at least n=4. and we want to compute an element x whose rank is (roughly) between n=4 and 3n=4. we could just BubbleSort each group and take the middle element. We will return to this later. we will describe a rather complicated method for computing a pivot elem ent that achieves the desired properties. To establish the correctness o f this procedure. We do not need an intelligent algorithm to do this. Copy the group medians to a new array B. but a careful analysis will show that the expected running time is still (n). Let x be this median of medians. The algorithm is illustrated in the figure below. where m = dn=5e. and repeating this dn=5e times will give a total running time of (n). Select(B. Recall that we are given an array A[1::n]. Instead. This can easily be done in (n) time. we might be co ntinuously unlucky. since each group has only a constant number of elements. e. m. There will be exactly m = dn=5e such groups (the last one might have fewer than 5 elements).

43 2 32 3 63 12 52 23 64 34 17 44 5 19 8 27 10 41 25 25 43 30 32 2 63 52 12 23 3 34 44 17 27 10 8 19 48 41 60 1 29 11 39 58 Get median of medians (Sorting of group medians is not really performed) 6 43 30 32 2 64 5 34 44 17 29 11 39 58 55 21 .

We achieved the main goal.) And for each g roup median. B y definition we have T(n) = T(n=5) + T(3n=4) + n: . This is a bit complicated. and write the (n) as n for concreteness. We will then show that T(n) cn. To do this. (Because x is their median. The other part of the proof is essentially symmetrical. such that T(n) cn. and so T(n) cn as long as c 1. in order to achieve this. Analysis: The last order of business is to analyze the running time of the overa ll algorithm. The running time is T(n) 1 if n = 1. Theorem: There is a constant c. 71: Choosing the Pivot. As usual. there are at least 3((n=5)=2 = 3n=10 n=4 elements that are le ss than or equal to x in the entire array. T(n=5) + T(3n=4) + n otherwise. within Select Pivot() we needed to make a recursive call to Sel ect() on an array B consisting of dn=5e elements.41 60 1 24 64 5 55 21 Get group medians 37 57 14 37 6 Fig. We know we want an algorithm that ru ns in (n) time. Proof: (by strong induction on n) Basis: (n = 1) In this case we have T(n) = 1. due to the floor and ceiling arithmetic. This mixture will make it impossible to use the Master Theorem. Lemma: The element x is of rank at least n=4 and at most 3n=4 in A. and difficult to appl y iteration. so to simplify things we w ill assume that n is evenly divisible by 5. namely that of eliminating a constant fraction (at least 1=4) of the remai ning list at each stage of the algorithm. However. Everything else took only (n) time. we need to show that there are at least n=4 elements that are less than or equal to x. we wi ll ignore floors and ceilings. this is a good place to apply constructive induction. Proof: We will show that x is of rank at least n=4. Step: We assume that T(n0) cn0 for all n0 < n. Consider the groups shown in the tabular form above. Therefore. The recursive call in Select() will be made to list no larger than 3n =4. This is a very strange recurrence because it involves a mixture of different fra ctions (n=5 and 3n=4). there are three elements that are less than or equal to this median within its group (beca use it is the median of its Lecture Notes 107 CMSC 451 group). 30 is the final pivot. However. Observe tha t at least half of the group medians are less than or equal to x.

A careful analysis involves understanding a bit abou t probabilistic analyses of algorithms.Since n=5 and 3n=4 are both less than n. we can apply the induction hypothesis. we are done. you will see that it works for any value that is strictly greater than 4. provided that we select c such that c (19c=20) + 1. A discrete random variable can be thought of as variable that takes on some Lecture Notes 108 CMSC 451 set of discrete values with certain probabilities. let Xi denote the random variable that indicates the number of elements assigned to the i-th bucke . Since we haven’t done any probabilistic analyses yet. or 6 and see what happens. the expected insertion time for each bucket is only a constant. Thus. A natural question is why did we pick groups of 5? If you look at the proof abov e. we see that by letting c = 20. (You might try it replacing the 5 wit h 3. let’s try doing th is one.) The first thing to do in a probabilistic analysis is to define a random variable that describes the essential quantity that determines the execution time. Combining the constraints that c 1.) Supplemental Lecture 5: Analysis of BucketSort Probabilistic Analysis of BucketSort: We begin with a quick-and-dirty analysis o f bucketsort. Therefore the expected running time of the algorithm is (n). More formally. Fo r 0 i n − 1. we would expect a constant n umber of items per bucket. giving T(n) c n 5 + c 3n 4 + n = cn 1 5 + 3 4 + n = cn 19 20 + n = n 19c 20 + 1 : This last expression will be cn. and the items fall uniformly between them. (This one is rather typical. and c 20. Solving for c we see that this is true provided that c 20. 4. This quick-and-dirty analysis is probably good enough to co nvince yourself of this algorithm’s basic efficiency. it is a functi on that maps some some discrete sample space (the set of possible values) onto the reals (the probabilities). Since there are n buckets.

Most techniques for encryption are based on number-theoretic techniques. Summing up over all n buckets. gives a total running time of (2n) = (n). We normally think of this algorithm as applying on a digit-by-digit basis. Divide-and-Conquer Algorithm: We know the basic grade-school algorithm for multi plication. Long Integer Multiplication: The following little algorithm shows a bit more abo ut the surprising applications of divide-and-conquer. The problem that we want to consider is how to perform arith metic on long integers. Supplemental Lecture 6: Long Integer Multiplication Read: This material on integer multiplication is not covered in CLRS. which can be quite costly when lo ts of long multiplications are needed. This raises the question of whether there is a more efficient way to multiply tw o very large numbers. we will see that it is possible. w y x z wz xz wy xy wy wz + xy xz . Addition and subtraction on large numbers is relatively easy. In fact. It would seem surprising if there were. for large n the time to insert the items into any one of the linked lists is a just shade less than 2. then these algorithms run in (n) time. (Go back and analyze your solution to the problem on Homework 1) . and multiplication in particular. The reason for doing arithmetic on long numbers st ems from cryptography. This is exactly w hat our quick-and-dirty analysis gave us. the character string to be encrypted is converted into a sequence of numbers. and encryption keys are store d as long integers.an derive this as E[X2] = Var[X] +E2[X] = np(1 − p) + (np)2 = n n 1 − 1 n + n n 2 = 2− 1 n : Thus. But the standard algorithm for multiplication runs in (n2) time. If n is the number of digits. but now we know it is true with confidence. For example. since for centuries people have used the same alg orithm that we all learn in grade school. the same multiplication rule still applies. typically containing hundreds of digits. but if we partition an n digit number into two “super digits” with roughly n=2 each into longer sequences. Efficient Lecture Notes 109 CMSC 451 encryption and decryption depends on being able to perform arithmetic on long nu mbers.

we can express A and B as A = w 10m + x B = y 10m + z. and E = (wz + xy). and so is not really a multiplication. The number of additions (as long as it is a constant) does not affect the running time. it took us four multiplications to compute these. since the number of additions must be a constant. its running time would be given by the following recurrence T(n) = 1 if n = 1. So. and a > bk. we can express the multiplicati on of two long integers as the result of four products on integers of roughly half the length of the original. and a constant number of additions and shifts. Unfortunately. observe that if instead we compute the following quantities. Let w = A[n − 1::m] x = A[m − 1::0] and y = B[n − 1::m] z = B[m − 1::0]: If we think of w. 72: Long integer multiplication. using only t hree multiplications (but with . Howe ver. D = xz. 4T(n=2) + n otherwise. It shows that the critical element is the num ber of multiplications on numbers of size n=2. This suggests that if we were to implement this algorithm. we see that a = 4. Thus. z) + mult(x. b = 2.n n/2 n/2 A B Product Fig. y))10m + mult(x. this is no better than the stan dard algorithm. imp lying that Case 1 holds and the running time is (nlg 4) = (n2). Faster Divide-and-Conquer Algorithm: Even though the above exercise appears to h ave gotten us nowhere. y and z as n=2 digit numbers. and so they take (n) time each. Let m = n=2. k = 1. Above. (Of course. we cannot simulate multiplication through repeated additions.) The key turns out to be a algebraic “trick”. The quantities that we need to compute are C = wy. To avoid complicating things with floors and ceilings. and their product is mult(A. then we would have a more efficient algorithm. it is more natural to think of the elements of A as being indexed in decreasing order from left to right as A[n − 1::0] rather than the usual A[0::n − 1]. it actually has given us an important insight. but by tradin g off multiplications in favor of additions. y)102m + (mult(w. x. let’s just assume that the number of digits n is a power of 2. Let A[0] denote the least signifi cant digit and let A[n−1] denote the most significant digit of A. if we could find a way to arrive at the same result algebraically. Lecture Notes 110 CMSC 451 If we apply the Master Theorem. each taking (n) time. Because of the way we write numbers. independen t of n. Observe that all the additions involve numbers involving roughly n=2 digits. we can get everything we want. z): The operation of multiplying by 10m should be thought of as simply shifting the number over by m positions to the right.B) = mult(w. Let A and B be the two numbers to multiply.

: : : . Is this really an improvement? This algorithm carries a larger constant factor b ecause of the overhead of recursion and the additional arithmetic operations.) More formally. and 2 subtractions all of proper final positions. The burglar carries a knapsack capable of holding total weight W. (y + z)) − C − D = (wy Finally we have mult(A. w2 : : : . 0-1 Knapsack Problem: Imagine that a burglar breaks into a museum and finds n it ems. 5n1:585 versus n2) then this algorithm beats the simple algorithm for n 50. then the crossover would occur for n 260. If the overhead was 10 times larger. we have a = 3. b = 2 and k = 1. Now when we apply the Master Theorem. The burglar wishes to carry away the most valuable subset items subjec t to the weight constraint.more additions and subtractions). C = mult(w. subject to X i2T wi W: . given hv1. Supplemental Lecture 7: Dynamic Programming: 0–1 Knapsack Problem Read: The introduction to Chapter 16 in CLR. then this algorithm will be superior.2. For example. Let vi denote the value of the i-th item.2. vni and hw1. and let wi denote the weight of the i-th item. wni. ng (of objects to “take”) that maximizes X i2T vi. recall that in cryptogrphy applications. The material on the Knapsack Proble m is not presented in our text.B) = C 102m + E 10m + D: Altogether we perform 3 multiplications. But he would rather steal gold before lead for the same reason. so he/she must make a decision to take the object entirely or leave it b ehind. z) E = mult((w + x). A lthough this may seem like a very large number. We still need to shift the terms into their subtractions. So the total running time T(n) = + wz + xy + xz) − wy − xz = (wz + xy): 4 additions. a burglar would rather steal diamonds before gold because the value per pound is better. but is briefly discussed in Section 17. and shifts take (n) time in total. : : : . But asymptotics says that if n is larg e enough. v2. encryption keys of this length and longer are quite reasonable. if we assume that the clever algorithm has overhe ads that are 5 times greater than the simple algorithm (e. 3T(n=2) + n otherwise.g. yielding T (n) 2 (nlg 3) (n1:585). is given by the recurrence: 1 if n = 1. numbers with n=2 digitis. we wish to determine the subset T f1. For example. We assume that the burg lar cannot take a fraction of an object. The additions. y) D = mult(x. (There is a version of the Lecture Notes 111 CMSC 451 problem where the burglar can take a fraction of an object for a fraction of the value and weight. This is much easier to solve. and W > 0.

observe that V [0. W) { allocate V[0.Let us assume that the vi’s. It turns out that this problem is NP-complete. They key is to record for each entry V [i. vi +V [i−1. we can come up with an efficient solution. 0::W ]. : : : . j −wi]. 2. irre spective of j. j] = 0 for 0 j W since if we have no items then we have no value. this gives a reasonable approximation algorithm. j] = V[i−1.n]. Lecture Notes 112 CMSC 451 0-1 Knapsack Problem KnapSack(v[1. then there is no value. j]. (Note that this is not very good if W is a large in teger. An example is shown in the figure below. We show that this problem can be solved in O(nW) time. we can see that we have the followin g rule for constructing the array V .. which is O((n + 1)(W + 1)) = O(nW ). With the remaining j−wi capacity in the knapsack. j] we will store the maximum value of any subset of objects f1. j] in the matrix whether we got this entry by taking the ith item or leaving it. With this information. The final output is V [n.n][0.n]. This is vi + V [i − 1. This is only possible if wi j. The algorithm is given below. This reflects the selection of items 2 and 4. j] if wi > j max(V [i − 1. ig that can fit into a knapsack of weight j.W] = V[4. We consider two cases : Leave object i: If we choose to not take object i. of values \$40 and \$50.) Here is how we solve the problem. To compute the entries of the array V we will imply an inductive approach.W] will contain the maximum value of all n objects that can fit into the entire knapsack of weight W. and that W itself is a small integer. As a basis. 10] = 90. then the array entry V [n. j] = 0 V[i. If we can compute all the entries of this array. 2. respectively and weights 4 + 3 10. i− 1g. For 1 i n. The ranges on i and j are i 2 [0::n] and j 2 [0::W ]. 2. The only missing detail is what items should we select to achieve the maximum. W e will leave this as an exercise. j]. Take object i: If we take object i. We assume that the wi’s are small integers..W]. : : : . w[1. V [0. We construct an array V [0::n. It is very easy to take these rules an produce an algorithm that computes the ma ximum value for the knapsack in time proportional to the size of the array. then the optimal value will c ome about by considering how to fill a knapsack of size j with the remaining objects f1. then we gain a value of vi but have used up wi of our capacity. The second line implements the rule above.. However if we make t he same sort of assumption that we made in counting sort. This is just V [i − 1. wi’s and W are all positive integers. : : : . Since these are the only two possibilities. . we can fill it in the best possible way w ith objects f1. and so we cannot really hope to find an efficient solution. i−1g. But if we truncate our numbers to lower precision. the entry V [i. j −wi]) if wi j The first line states that if there are no objects. and 0 j W.. it is possible to reconstruct the opt imum knapsack contents. n.

73: 0–1 Knapsack Example.for j = 0 to W do V[0. j) co mputes and returns the value of m[i.j] = cost. // initialization for i = 1 to n do { for j = 0 to W do { leave_val = V[i-1. The initial call is Rec-Matrix-Chain(p. j . We only con sider the cost here. Fig.j] = 0. // final value is max } } return V[n. // initialize for k = i to j-1 do { // try all splits cost = Rec-Matrix-Chain(p. // basis case else { m[i.j] = INFINITY. 1. // update if better } } return m[i. 3i. Capacity ! j = 0 1 2 3 4 5 6 7 8 9 10 Item Value Weight 0 0 0 0 0 0 0 0 0 0 0 1 10 5 0 0 0 0 0 10 10 10 10 10 10 2 40 4 0 0 0 0 40 40 40 40 40 50 50 3 30 6 0 0 0 0 40 40 40 40 40 50 70 4 50 3 0 0 0 50 50 50 50 90 90 90 90 Final result is V [4. Lecture Notes 113 CMSC 451 Supplemental Lecture 8: Dynamic Programming: Memoization Read: Section 15. take_val). n = j−i+1. 30. j] = 0. k) + Rec-Matrix-Chain(p. Must the computation proceed bottom-up? Consider the following recursive implementation of the chain-matrix multiplication algorithm. 1::n] is not really needed. j) + p[i-1]*p[k]*p[j].w[i]]. j]. Recursive Chain Matrix Multiplication Rec-Matrix-Chain(array p. we will see that its running time is exponential in n. int j) { if (i == j) m[i. 50i. This is unacceptably slow. The call Rec-Matrix-Chain(p. i. if (cost < m[i. n).3 of CLRS.j] = max(leave_val. W]. i. } Values of the objects are h10.) This version of the procedure certainly looks much simpler. int i. // total value if we take i else take_val = -INFINITY.) . 10] = 90 (for taking items 2 and 4). what is wron g with this? The answer is the running time is much higher than the (n3) algorithm that we gav e before. Let T(n) denote the running time of this algorithm on a sequence of matrices of length n.j]) m[i. We show it just to make the connection with the earlier version clearer. So. k+1. (That is. However. // total value if we leave i if (j >= w[i]) // enough capacity to take i take_val = v[i] + V[i-1. an d more closely resembles the recursive formulation that we gave previously for this problem. the recursive formulations that we have derived have been set up in a “topdown” manner. // return final cost } (Note that the table m[1::n.j]. 4. Recursive Implementation: We have described dynamic programming as a method that involves the “bottom-up” computation of a table. 40. // cannot take i V[i. Weights of the objects are h5. j]. 6. In fact.

we do (1) work and then consider all possible ways of splitting the sequence of length n into two sequen ces. It’s job is to compute m[i. while keeping the same O(n3) efficiency of the bottom-up version? The answer is yes. // already defined else if (i == j) m[i. through a techniqu e called memoization. Memoization: Is it possible to retain the nice top-down structure of the recursi ve solution. the induction hypothesis is that T(m) 2m−1 for allm < n. since T(1 ) = 1 = 20.j]. defined for n 1. As noted above. and return its value. Claim: T(n) 2n−1. the main problem with the procedure is tha t it recomputes the same entries over and over. 1 + Pn−1 k=1(T(k) + T(n−k)) if n 2.g. UNDEFINED). Using this we have T(n) = 1+ nX−1 k=1 (T(k) + T(n−k)) 1 + nX−1 k=1 T(k) 1 + nX−1 k=1 2k−1 = 1+ nX−2 k=0 2k = 1+(2n−1−1) = 2n−1: In the first line we simply ignored the T(n−k) term.j] != UNDEFINED) return m[i. we will fix this by allowing the procedure to compute each en try exactly once. int j) { if (m[i. Otherwise. So we get the f ollowing recurrence. and the time is (1). Here is the idea.) T(n) = 1 if n = 1. and in the last line we applied the formula for the geometric series.j] = 0. Memoized Chain Matrix Multiplication Mem-Matrix-Chain(array p. Let’s reconsider the function Rec-Matrix-Chain() given above. j]. Proof: The proof is by induction on n. Lecture Notes 114 CMSC 451 Why is this so much worse than the dynamic programming version? If you “unravel” the recursive calls on a reasonably long example. you will see that the procedure is called repeatedly wi th the same arguments. int i. So. // initialize . Clearly this is true for n = 1. Onc e an entries value has been computed. // basis case else { m[i.If i = j then we have a sequence of length 1. (We have replaced the (1)’s with the constant 1. and invoke the procedure recursively on each one. One way to do this is to initialize every entry to some special value (e.j] = INFINITY. in the second line we applied the induction hypothesis. In general. for n 2. one of length k and the other of length n − k. it is never recomputed. The bottom-up version evaluates each entry exactly once.

and so bot tom-up computation may compute entries that are never needed. this time to a problem on undirected graphs. j) as the hash key. because these are the “critical” points. k+1. many of the table entries are simply not needed. Lecture Notes 115 CMSC 451 Bridge Articulation point c Biconnected b g h f i d c g h components j a e e i c a b f d j . (See Chapter 11 in CLRS for more information on hashing. in some DP problems. Articulation Point (or Cut Vertex): Is any vertex whose removal (together with t he removal of any incident edges) results in a disconnected graph. here is a way to save space. Bridge: Is an edge whose removal results in a disconnected graph. // return final cost } This version runs in O(n3) time. // update if better } } return m[i.for k = i to j-1 do { // try all splits cost = Mem-Matrix-Chain(p. whose failure will result in the network becoming d isconnected. However. If you have know that most of the table will not be needed. (In g eneral a graph is k-connected. if (cost < m[i.j].j]) m[i. using the index pair (i. Biconnected: A graph is biconnected if it contains no articulation points. you can store the “defined” entries of the table in a hash table. since it is generally slower than t he bottom-up method.j] = cost. if k vertices must be removed to disconnect the graph. this is because each of the O(n2) table entries is only computed once. and the work needed to compute one table entry (most of it in the for-loop ) is at most O(n). Articulation Points and Biconnected Graphs: Today we discuss another application of DFS. Consider th e following definitions.) Supplemental Lecture 9: Articulation Points and Biconnectivity Read: This material is not covered in CLR (except as Problem 23–2).E) be a connected undirected graph.) Biconnected graphs and articulation points are of great interest in the design o f network algorithms. Rather than s toring the whole table explicitly as an array. Let G = (V. j) + p[i-1]*p[k]*p[j]. i. Intuitively. In these cases memoization may be a good idea. k) + Mem-Matrix-Chain(p. Memoization is not usually used in practice.

Biconnected components: The biconnected components of a graph are the equivalenc e classes of the cocylicity relation. and we ju st call them back edges. can it be an articulation point? Answer: No. What about the leaves? If u is a leaf. (You should take a moment to convince yourself why thi s is true. We say that two edges e1 and e 2 are cocyclic if either e1 = e2 or if there is a simple cycle that contains both edges. this subtree would become disconnected from the rest of the graph. An algorithm for computi ng bridges is simple modification to this procedure. T his leads to the following. You might th ink for a while why this is so. : : : . Notice that if two edges are cocyclic. v2.a e Fig. If for some child. if every one of the subtrees rooted at the children of u have back edges to prop er ancestors of u. where u is not a leaf a nd u is not the root. there is no back edge going to a proper ancestor of u. It is not too hard to ve rify that this defines an equivalence relation on the edges of a graph. In particul ar. and hence u is an articula tion point. then th ere are essentially two different ways of getting from one edge to the other (by going around the the cycle each w ay). and use the tree structure provided by the search to aid us. let us ask ourselves if a vertex u is an articulation point. Notice that unlike strongly connected components of a digraph (which form a part ition of the vertex set) the biconnected components of a graph form a partition of the edge set. we cannot distinguish between forward edges and back edges. In particul ar. Observation 1: An internal vertex u of the DFS tree (other than the root) is an articulation point if and only there exists a subtree rooted at a child of u such that there is no back edge fr om any vertex in this subtree to a proper ancestor of u. then if we we re to remove u. then if u is removed. So we assume is only one tree in the DFS forest. vk be the children of u. For each child there is a subtree of th e DFS tree rooted at this child.) For now. On the other hand. Because G is undirected. we can apply this algorithm to each indiv idual connected component). the graph remains connected (the backedges hold everything together). how would we know it by its structure in the DFS tree? We assume that G is connected (if not. Articulation Points and DFS: In order to determine the articulation points of an undirected graph. Th is is the most common source of confusion for this algorithm. We would like to do the same thing here. 74: Articulation Points and Bridges Last time we observed that the notion of mutual reachability partitioned the ver tices of a digraph into equivalence classes. there are no cross edges. we will call depthfirst search. Please check this condition carefully to see that you understand it. First off. the DF S tree has a simpler structure. let us consider the typical case of a vertex u. Also. We give an algorithm for computing articulation points. notice that the condition for whether u is an articulation point depends on a test applied to its children. because when you delete a . Let’s let v1.

) To compute Low[u] we use the following simple rules: Suppose that we are perform ing DFS on the vertex u. Low: Define Low[u] to be the minimum of d[u] and fd[w] j where (v. Lecture Notes 116 CMSC 451 Low[u]=d[v] v u Fig. If any back edge goes to an an cestor of u. Initialization: Low[u] = d[u]. Explanation: Since v is in the s . Back edge (u. in the sense of being close to the root.w) that has the smallest value of d[ w]. d[v]). not lo w in the tree. since a leaf will not have any subtrees in the DFS tree. v): Low[u] = min(Low[u]. How can we do this? It would be too expensive to keep track of all the b ack edges from each subtree (because there may be (e) back edges. that is. v): Low[u] = min(Low[u]. In fact Low[u] tends to be “high” in the tree. then (as in the case of leaves) its removal do es not disconnect the DFS tree. (Beware of this notation: “Low” means low discovery time. 2. Observation 3: The root of the DFS is an articulation point if and only if it ha s two or more children. Note that this is completely consistent with Observation 1. So we keep track of the back edge (v. the rest of the tree remains connected. thus even ignoring the back edges. Articulation Points by DFS: Observations 1.w) is a back edge and v is a descendent of ug: The term “descendent” is used in the nonstrict sense. Low[v]). Checking Observation 1 is the hardest. A simpler scheme is to keep track of back e dge that goes highest in the tree (in the sense of going closest to the root). and hence cannot disconnect the graph in general. On the other hand. 75: Articulation Points and DFS Observation 2: A leaf of the DFS tree is never an articulation point. so we can delete the word “internal” from Observation 1. Intuitively. v may be equal to u. but we will exploit the structure of the DFS tree to help us. What about the root? Since there are no cross edges between the subtrees of the root if the root has two or more children then it is an articulation point (since its removal separates these two subtrees). Explanation: We have detected a ne w back edge coming out of u. How can we design an algorithm which te sts these conditions? Checking that the root has multiple children is an easy exercise. Low[u] is the highest (closest to the root) that you can get in the tree by taking any one bac kedge from either u or any of its descendents.leaf from a tree. and 3 provide us with a structura l characterization of which vertices in the DFS tree are articulation points. How do we know how close a back edge goes to the root? As we travel from u towar ds the root. Tree edge (u. the graph is connected after the deletion of a leaf from the DFS tree. If this goes to a lower d value than the previous back edge then make this the new low. observe that the discovery times of these ancestors of u get smaller and smaller (the root ha ving the smallest discovery time of 1). if the root has only a single child. The basic thing we need to check for is whether there is a back edge from some s ubtree to an ancestor of a given vertex. this one will.

Lecture Notes 117 CMSC 451 Observe that once Low[u] is computed for all vertices u. The complete algorithm for computing articulation points is given below.v) is a back edge Low[u] = min(Low[u]. we need to k now when a given edge (u. we can test whether a g iven nonroot vertex u is an articulation point by Observation 1 as follows: u is an articulation point if an d only if it has a child v in the DFS tree for which Low[v] d[u] (since if there were a back edge from either v or one of its descendents to an ancestor of v then we would have Low[v] < d[u]). This can be done by a small modification of the algorithm ab ove. d[v]) // update L[u] } } } An example is shown in the following figure. Low[v]) // update Low[u] if (pred[u] == NULL) { // root: apply Observation 3 if (this is u’s second child) Add u to set of articulation points } else if (Low[v] >= d[u]) { // internal node: apply Observation 1 Add u to set of articulation points } } else if (v != pred[u]) { // (u. As with all DFS-based algorithms. There are some interesting problems that we still have not discussed. The Final Algorithm: There is one subtlety that we must watch for in designing t he algorithm (in particular this is true for any DFS on undirected graphs). The mai n procedure for DFS is the same as before. vg is a bridge then it does not follow that u and v are both articulation points. To test correctly for a back edge we use the predecessor pointer to check that v is not the parent of u in the DFS tree. When processing a vertex u. We’ll leave it as an exercise. t he running time is (n + e). We did not discuss how to compute the bridges of a graph.) Another question is how to determine which edges are in the biconnected componen .ubtree rooted at u any single back edge leaving the tree rooted at v is a single back edge for the tree rooted at u. except that it calls the following routine rather than DFSvisit( ). (Notice that if fu. This is not quite correct because v may be the parent of v in the DFS tree and we are just seeing the “other side” of the tree edge between v and u (recal ling that in constructing the adjacency list of an undirected graph we create two directed edges for each undi rected edge). How do we do this? An almost correct answer is to test whether v is colored gray (since all gray vertices are ancestors of the current vertex). Articulation Points ArtPt(u) { color[u] = gray Low[u] = d[u] = ++time for each (v in Adj(u)) { if (color[v] == white) { // (u. v) is a back edge.v) is a tree edge pred[v] = u ArtPt(v) Low[u] = min(Low[u].

ts. v). you can show that all the edges in the biconnected component will be consecutive in the stack . L ike Dijkstra’s algorithm. w(u. Bellman-Ford Algorithm: We saw that Dijkstra’s algorithm can solve the single-sour ce shortest path problem. What if you have negative edge weights. It was described in our discussion of Dijk . have cycles of total negative cost. but no negative cost cycles? We shall present the Bellman-Ford algorithm.1 in CLRS. Supplemental Lecture 10: Bellman-Ford Shortest Paths Read: Section 24. A hint here is to store the edges in a stack as you go through the DFS search. This algori thm is slower that Dijkstra’s algorithm. (Recall that relaxation updates shortest path information along a single edge. under the assumption that the edge weights are nonnegative. the Bellman-Ford algorithm is based on performing repeated relaxations. 76: Articulation Points.) Recall that we are given a graph G = (V. (Che ck it out. which solves this problem. 2 4 5 6 3 3 1 1 8 7 9 8 8 8 d d=1 Low=1 e i f j g h d c b a j a e i b f c g h Fig. The one presented in CLRS actually contains a bit of code that checks for this. We also saw that shortest paths are undefined if you Lecture Notes 118 CMSC 451 1 3 10 3 = articulation pt.E) with numeric edge weights. When you come to an artic ulation point. running in (V E) time. In our version we will assume that there are no negative cost cycles.

: : : .stra’s algorithm.) Dijkstra’s algorithm was based on the idea of organizing the relaxations in the best possib le manner. Correctness of Bellman-Ford: I like to think of the Bellman-Ford as a sort of “Bub bleSort analogue” for shortest paths. we know that k V − 1. the Bellma n-Ford algorithm simply applies a relaxation to every edge in the graph.w. v1.s) { for each (u in V) { // standard initialization d[u] = +infinity pred[u] = null } d[s] = 0 for i = 1 to V-1 { // repeat V-1 times for each (u. namely in increasing order of distance. vi): Lecture Notes 119 CMSC 451 −6 −6 −6 4 5 5 −6 5 8 4 8 4 8 4 5 8 phase phase phase Initial configuration After 1st relaxation After 2nd relaxation After 3rd relaxa tion 8 9 2 8 0 4 0 8 0 7 2 . vi) (the true shortest p ath cost from s to vi) satisfies (s. Instead. since there are two main nested loops. This trick doesn’t seem to work when dealing with graphs with negative edge weights. in the sense that shortest path information is propagated sequentially al ong each shortest path in the graph. Once relaxation is applied to an edge.v) } } } The (V E) running time is pretty obvious. and he nce the path consists of at most V −1 edges. Bellman-Ford Algorithm BellmanFord(G. vi) = (s. Since this is a shortest path we have (s.v) in E { // relax along each edge Relax(u. it need never be relax ed again. vi−1) +w(vi−1. and repeats this V − 1 times. vki w here v0 = s and vk = u. Since a shortest path will never visit the same vertex twice. The interesting question is how and why it works. one iterated V −1 times and the other iterated E times. Consider any shortest path from s to some other vertex u: hv0.

f : V V ! R which satisfi es the following three properties: Capacity Constraint: For all u.E) is a directed graph in which each edge ( u. Flow Networks: A flow network G = (V. vi) = (s. u). The idea is to find out how much flo w we can push from one point to another. (In other words. These are often studied in business schools. vi). after the (V − 1)st iteration of the for loop. pri or to the ith pass through the loop. and operations research. vi) (since each time we do a relaxation there exists a path that witnesses its value). In summary. v) 0. Intuitively we can think of a flow network as a directed graph in which fluid is flowing along the edges of the graph. Maximum Flow: The Max Flow problem is one of the basic problems of algorithm des ign. tg. since we think of ourselves as pumping fl ow from s to t. v) c(u. (This implies that the digraph is connected. v 2 V . v) 62 E we model this by setting c(u. and hence e n − 1. Flow . This is primarily for making algebraic analysis easier. v 2 V . vi). 77: Bellman-Ford Algorithm. routing in n etworks. v) = −f(v. vi): Recall from Dijkstra’s algorithm that d[vi] is never less than (s. Observe that after the initialization (pass 0) we have d[v1] = d[s] = 0.) Note th at flow conservation does NOT apply to the source and sink.) Flow conservation: For all u 2 V − fs. v) 2 E has a nonegative capacity c(u. all vertices u have the correct distance values stored in d[u]. It is the simplest problem in a line of many important problems having to do with the movement of c ommodities through a network. d[vi] is in fact equal to (s. In general. we have done a relaxation on the edge (vi−1.) A flow is a real valued function on pairs of vertices. and a sink t. flow-in = flow-out. Thus.? ? ? ? 0 Fig. Each edge has certain maximum capacity that it can carry. v). all vertices that are i edges a way (along the shortest path tree) from the source have the correct distance values stored in d[u]. Thus. If (u. Skew Symmetry: For all u. The proof is by induction on i. We assert that after the ith pass of the “for-i” loop that d[vi] = (s. The max flow problem has applications in areas like transportation. vi) = (s. vi−1) +w(vi−1. Supplemental Lecture 11: Network Flows and Matching Read: Chapt 27 in CLR. f(u. we can thin k of backwards flow as negative flow. vi) (since we do relaxations along all the edges). the induction hypothesis tells us that d[vi−1] = (s. we have X v2V f(u. completing the induction proof. We assume that every vertex lies on some path from the s ource to the sink (for otherwise the vertex is of no use to us). vi−1). f(u. v) = 0: Lecture Notes 120 CMSC 451 (Given skew symmetry. There a re two special vertices: a source s. after i passes through the for loop. T hus after the ith pass we have d[vi] d[vi−1] +w(vi−1. v) = 0. After the ith pass throug h the loop. this is equivalent to saying.

given a flow network.e. The maximum-flow problem is. We will show this later. (iii) If X \ Y = .Z) and f(Z. then you have a tougher problem called the multi-c ommodity flow problem. and attaching s0 to all the si and attach all the tj to t0. : : : . It turns out that this is also equal to P v2V f(v. multi-sink flow problems: It may seem overly restrictive to requir e that there is only a single source and a single sink vertex. Now by pushing the maximum flow from s0 to t0 we are effectively producing the m aximum flow from all the s0 i to all the tj ’s. To do this we exten d the definition of f to sets by defining f(X. The total value of the flow f is defined as jfj = X v2V f(s.Z) + f(Y. Example: Page 581 of CLR. Note that we don’t care which flow from one source goes to another sink. This can easily be modelled by just addin g a special supersource s0 and a supersink t0. Y ). Lemma: (i) f(X. Ford-Fulkerson Method: The most basic concept on which all network-flow algorith ms work is the notion of augmenting flows.X) = 0. The idea is to start with a flow of size zero. v) is called the net flow from u to v.X). Set Notation: Sometimes rather than talking about the flow from a vertex u to a vertex v. V ) = 0. v) i. tl. t). In this case f(X. t2. The quantity f(u.e. We let these edges have infinite capacity. Y ) can be thought of as th e net amount of flow crossing over the cut. (ii) f(X. s2. : : : . thus the f low out of s will equal the flow into t. Y ) = −f(Y. sk and many sink vertices t1.X) + f(Z.conservation means that no flow is lost anywhere else in the network. and source and sink vertices s and t. Y ) = X x2X X y 2 Y f(x.Z) = f(X. Multi-source.X [ Y ) = f(Z. If you re quire that the flow from source i goes ONLY to sink i. we want to talk about the flow from a SET of vertices X to another SET of vertices Y . the flow into t. the flow out of s. One important special case of this concept is when X and Y define a cut (i. Many flow problems have situations in which many sourc e vertices s1. y): Using this notation we can define flow balance for a vertex u more succintly by just writing f(u. From simple manipulations of the definition of flow we can prove the following f acts. and then incrementally mak e the flow larger and . then f(X [ Y. find the flow of maximum value from s to t. a part ition of the vertex set into two disjoint subsets X V and Y = V − X).

we have to push −cf (p) units of flow along the reverse edge (v. v) > 0.e. (Remember that when defining this flow that whenever we push cf (p) units of flo w along any edge (u. a locally m aximum flow is globally maximum). and hence we can use thi s to augment the flow in G. Because of the capacity constraint. the resulting flow is strictly larger than the current flow for G. We will prove that when it is impossible to “push” any more flow through the network. define the residual capacity of a pair u. First we construct the residual network. u) to maintain sk ew-symmetry. Given a flow network G and a flow f. called the Ford-Fulkerson method. Otherwise we say that the edge is saturated. } Residual Network: To define the notion of an augmenting path. v) = c(u. v) of p. The value of the flow is jfj + jf0j. They only diff er in how they decide which path or paths along which to push flow. The other rules for flows are easy to verify. Then (f + f0) (defined ( f + f0)(u.larger by finding a path along which we can push more flow. Each edge in the residual network is weighted with its residual capacity. t) { initialize flow f to 0. s. Lecture Notes 121 CMSC 451 Ford-Fulkerson Network Flow FordFulkerson(G. v) > 0 t hen it is possible to push more flow through the edge (u. cf (u. If the search reaches t then we know that a path exists (and can follow the predecessor pointers backw ards to reconstruct it). Observe that if cf (u. v) 0. In order to determine whether there exists an augmenting path from s to t is an easy problem. Lemma: Let f be a flow in G and let f0 be a flow in Gf. while (there exists an augmenting path p) { augment the flow along p. v). Observe that by pushing cf (p) units of flow along each edge of the path. v)) is a flow inG. we get a flow in Gf . The re sidual capacity of the path is the MINIMUM capacity of any edge on the path. we have reached the maximum possible flow (i. } output the final flow f. v 2 V t o be cf (u. v). The residual network is the directed graph Gf with the same vertex set as G but whose edges are the pairs (u. It is denoted cf (p). Almost all network flow algorithms are based on this simple idea. This implies that f + f0 never exceeds the overall edge capacities of G. Augmenting Paths: An augmenting path is a simple path from s to t in Gf . and then we run DFS or BFS on the residual network startin g at s. v) = f(u. A path in the networ k from s to t along which more flow can be pushed is called an augmenting path. v) such that cf (u. Since every edge of the residual network has a strictly positive weight. Example: Page 589 of CLR. v) + f0(u. v)−f(u. we first define th e notion of a residual network. Since DFS and BFS take (n + e) time. Proof: Basically the residual network tells us how much additional flow we can p ush through G. and it can be shown that the residual network has ( . This idea is given by the most simple method for computing network flows.

called the Max-Flow. T) forms a cut. V ) = f(s. T) = f(S. T) flows from T t o S are counted negatively (by skew-symmetry). then it must be maximum (and this cut must be minimum). if the flow equals the capacity of some cut. (ii) The residual network Gf contains no augmenting paths. T). Note that in computing f(S. Proof: You cannot push any more flow through a cut than its capacity. T) of G. a contradiction. (ii) ) (iii): If there are no augmenting paths then s and t are not connected in the residual network. Let S be those vertices reachable from s in the residual network and let T be the re st. T) for some cut (S. in a flow network is a part ition of the vertex set into two disjoint subsets S and T such that s 2 S and t 2 T. T). Max-Flow Min-Cut Theorem: The following three conditions are equivalent. it follows that the flow across the cut equals the capacity of the cut. T). Proof: (i) ) (ii): If f is a max flow and there were an augmenting path in Gf . The correctness of the Ford-Fulkerson method is based on the following theorem. It basically states that in any flow network the minimum capacity cut a cts like a bottleneck to limit the maximum amount of flow. A cut. f(u. (S. (iii) jfj = c(S. Consider the following example (from page 596 in CLR). Lecture Notes 122 CMSC 451 Proof: f(S. the running time of Ford-Fulkerson is basically ((n + e)(number of augmenting stages)): Later we will analyze the latter quantity. V ) + f(S −s. T). Because each edge crossing the cut must be saturated with flow. V ) = f(s.) Corollary: The value of any flow is bounded from above by the capacity of any cu t. (i) f is a maximum flow in G. it may spend an inordinate amount of time arriving a the final maximum flow. If the algorithm were smart enough . and hence it finds the minimum cut and maximum flow. T) we ONLY count constraints on edges lead ing from S to T ignoring those from T to S). Analysis of the Ford-Fulkerson method: The problem with the Ford-Fulkerson algor ithm is that depending on how it picks augmenting paths. Correctness: To establish the correctness of the Ford-Fulkerson algorithm we nee d to delve more deeply into the theory of flows and cuts in networks. S) = f(S. Lemma: The amount of flow across any cut in the network is equal to jfj. thus jfj = c(S. Maximum flow Minimum cut).e. and since S − s is formed of such vertices the sum of their flows will be zero als o. V ) − f(S. (i. Min-Cut Theorem. and in computing c(S. Ford-Fulkerson algorithm terminates when it finds th is bottleneck. (S. and we define the capcity of the cut as c(S.n +e) size. (iii) ) (i): Since the flow is never bigger than the capacity of any cut. We define the flow across th e cut as f(S. V) = 0 comes from flow conservation. then by pushing flow along this path we would have a larger flow. V ) = 0 for all u other than s and t. V ) = jfj (The fact that f(S − s.

to send flow along the edges of weight 1. Lemma: For each vertex u 2 V −fs.000. v) f (s. How many times can an edge become critical before the algorithm terminates? Obse rve that when the edge (u. but there is another simple strategy that is guaranteed to give good bounds (in terms of n and e). u)+1 then u would not be on the shortest path from s to v. implying that f . v) is an edge on the minimum length augmenting path from s to t in Gf . tg. v) is not on any shortest path. after augmentation the critical edge becomes satur ated. but not too complicated. we use Breadth-First search in the residual network. and disappears from the residual graph. and thus we find the shortest augmenting path (where the length of the path is the number of edges on the path). u) + 1. and hence (u. We claim that this choice is particularly nice in that. v) is critical it lies on the shortest augmenting path. Proof: This is a simple property of shortest paths.000 augmenting will be needed before we get the final flow. An Improvement: We have shown that if the augmenting path was chosen in a bad wa y the algorithm could run for a very long time before converging on the final flow. u) increases monotonically with each flow augmentation. Then as we peform augmentations by the Edmonds-Karp algorithm the value of f (s. v) = f(s. starti ng at the source s. and if f (s. u) + 1. See the text. Since there is an edge from u to v. In other words. When finding the augmenting path. Proof: (Messy. if we do so. Since each augmentation takes O(n + e) time to compute using BFS. Computing this path is equivalent to determining the path of maximum capacity from s to t in th e residual network. f (s. Lecture Notes 123 CMSC 451 Edmonds-Karp Algorithm: The Edmonds-Karp algorithm is Ford-Fulkerson.) Theorem: The Edmonds-Karp algorithm makes at most O(n e) augmentations. the number of flow a ugmentations needed will be at most O(e n).) It is no t known how fast this method works in the worst case. the algorithm would terminate in two augmenting s teps. if the algorithm were to try to augment using the middle edge. (This is exactly the same as the beer transport problem given on the last exam. Observation: If the edge (u. (The best known algorithm is essentially O(e n log n): The fact that Edmonds-Karp uses O(en) augmentations is based on the following ob servations. the ov erall running time will be O((n + e)e n) = O(n2e+e2n) 2 O(e2n) (under the reasonable assumption that e n). let f (s. v) < f(s. Proof: An edge in the augmenting path is critical if the residual capacity of th e path equals the residual capacity of this edge. u) be the distance function from s to u in the residual network Gf . it will continuously improve the f low by only a single unit. Fo rd-Fulkerson can take time ((n + e)jfj) where f is the maximum flow. then f (s.000. 2. However. with one l ittle change. In general. It seems (from the example w e showed) that a more logical way to push flow is to select the augmenting path which holds the maximum amount of flow.000.

(s. observe that .e. (It may be that some men are not paired with any woman. there is at most one edge of M incident to v. it must be tha t we reduce flow on this edge. Using a questionaire you establish which men are compatible which which women. This problem is called the maximum bipartite matching problem. (An example is problem 3 in the homework. and vice versa. there are O(e) edges. (Note th at this idea does not work for general undirected graphs. we push flow along the reverse edge (v. v) = f(s. the algorithm must terminate. hence after O (ne) augmentations. its tail vertex increases in distance from the source by two. subject to the constraint that each man is paired with at most one woman. i. In summary. Example: See page 602 in CLR. Example: See page 601 in CLR. After this it disappears from the residual graph. The pro blem is to find a matching. the Edmonds-Karp algorithm makes at most O(ne) augmentations and run s in O(ne2) time. v) 2 Eg: Set the capacity of all edges in this network to 1. For this to be the case we have (at some later flow f0) f0 (s. In order to reappear. u 2 L. Your task is to pair up as many compatible pairs of men and women as possible. since no vertex can be further than n fr om the source. u) + 1) + 1 = f(s. v) + 1. E 0 = f(s. and is called a maximu m matching. t)jv 2 Rg [ f(u. between the time that an edge becomes critical. u) = f0(s. you are running a dating service and there are a set of men L and a set of women R. then you can use this algorithm to solve the maximum bipartite matching problem. Now. u)ju 2 Lg [ f(v. Thus we have: f0 (s. The desired matching is the one that has the maximum number of edges.) We will give another example here. unless the datin g service is located on Dupont Circle). v).E0) as follows. Thus. u) = f0(s. u) + 1.) Construct a flow network G0 = (V 0. v) + 1 f(s. Reduction to Network Flow: We claim that if you have an algorithm for solving th e network flow problem. v) + 1 since dists increase with time = (f(s. u). compute the maximum flow in G0. tg. Maximum Matching: One of the important elements of network flow is that it is a very general algorithm which is capable of solving many problems. each edge can become critical at most O(n) times. v)j(u. v 2 R such that u and v are compatible. u) + 2: Thus. The resulting undirected graph has the property that its vertex set can be divid ed into two groups such that all its edges go from one group to the other (never within a group. This can only happen n=2 times. Although in general it can be that flows ar e real numbers. Consider the following problem. Lecture Notes 124 CMSC 451 that is a subset of edges M such that for each v 2 V . Let s and t be two new vertic es and let V 0 = V [ fs.) This problem is modelled by giving an undirected graph whose vertex set is V = L [ R and whose edge set consists of pairs (u.

The Hamiltonian cycle (HC) and Hamiltonian path (HP) problems ask whether a given gr aph (or digraph) has such a cycle or path. Hamiltonian Cycle: Today we consider a collection of problems related to finding paths in graphs and digraphs. The decision problem formulation is . This type of reduction is called a component design reduction. most of the reductions that we have seen (for Cliqu e. and depending on whether you want a path or a cycle. labeled o1. (See CLR’s presentation of HP for other examples of gadgets. Since the graph is complete.the Ford-Fulkerson algorithm will only assign integer value flows to the edges ( and this is true of all existing network flow algorithms). it can have flow along at most 1 i ncoming edge. because they operate by making some local change throughout the graph. VC. called a DHP-gadget. We will leave TSP as an easy exercise. i3 and three o utgoing edges. and DS in particular) are of a relatively simple variety. it can have flow along at mo st 1 outgoing edge. respectively.4 of CLR. We will present a much more complex style of reduction for the Hamiltonian path problem on directed graphs. v) > 0g: We claim that this matching is maximum because for every matching there is a cor responding flow of equal value. Supplemental Lecture 12: Hamiltonian Path Read: The reduction we present for Hamiltonian Path is completely different from the one in Chapt 36. f(u.5.) The gadget that we will use in the directed Hamiltonian path reduction.) Lecture Notes 125 CMSC 451 Component Design: Up to now. This one invol ves the construction of only one. Given a co mplete graph (or digraph) with integer edge weights. Recall that given a graph (or digraph) a Hamiltonian cycle is a simple cycle tha t visits every vertex in the graph (exactly once). A Hamiltonian path is a simple path that visits every vertex in the graph (exactly once). we can define a matching M = f(u. There are four variations of these problems depen ding on whether the graph is directed or undirected. It . Thus by maximizing one we maximize the other. and integer X. An important related problem is the traveling salesman problem (TSP). determine the cycle of minimum weight that visits all the vertices. (I t is done in Section 36. Since each vertex in L has exactly 1 incoming edge. such a cycle will always exist. and for every (integer) flow there is a matching of equal value. given a complete weighted graph G. Thus letting f denote the maximum flow. v)ju 2 L. but all of these problems are NP-complete. Very complex reductions may involve the creation of many gadgets. is shown in the figure below. and since each vertex in R has exactly 1 outgoing edge. sometimes called components or gadgets (also called widgets). whose job it is to enforce a particular constraint. i2.5 in CLR. o3. v 2 R. o2.5. because it involv es designing special subgraphs. It consists of three incoming edges labeled i1. does there exist a Hamiltonian cycle of total weight at most X? Today we will prove that Hamiltonian Cycle is NP-complete. They are sometimes called local replacement redu ctions.

Lecture Notes 127 CMSC 451 .e will be paths coming into Lecture Notes 126 CMSC 451 i i2 i1 Gadget What it looks like inside 3 i 3 o 2 o 1 o i3 i2 i1 3 o 2 o 1 o i3 2 1 Path with 3 entries 3 o 2 o 1 o i3 i2 i1 3 o 2 o 1 o i3 i2 i2 i i1 3 o 2 o 1 o i3 i2 i1 3 o 2 o 1 o i i1 i 3 o 2 o 1 o i3 i2 1 Path with 2 entries Path with 1 entry 3 o 2 o 1 o 3 Fig. 78: DHP-Gadget and examples of path traversals.

.. then we w ill have at least one path passing through each of the gadgets whose corresponding clause contains xi. 79: General structure of reduction from 3SAT to DHP..) We add one final vertex xe. (If we wanted to reduce to Hamiltonian cycle. The construction y ields the digraph shown in the following figure. and if we ch ose the false path. then we will have at least one path passing through each gadget for xi.) xi xi xi i _ _ _ _ _ _ _ xi+1 . If we choose the true path for xi to be in the Hamiltonian path. the Hamiltonian path must either use the true path or the false path. For example. an d the last variable’s paths are connected to xe. .these same gadgets from other variables as well. _x x x i xi i xi xi xi xi xi xi xi xi xi xi Fig. we could join xe back to x1.. Note that for each variable. but it cannot use both. rather than Hamil tonian path. consider the following boolean formula in 3-CNF. (x1 _ x2 _ x3) ^ (x1 _ x2 _ x3) ^ (x2 _ x1 _ x3) ^ (x1 _ x3 _ x2): T F F T to to to to F _x _ x x _ 3 3 x x _ _ _ 2 2 1 x1 path starts here .

Proof: We need to prove both the “only if” and the “if”. the path mu st visit the variable vertices in increasing order from x1 until xe. We claim that G has a Hamiltonian path. the path will proceed along either t he true path or the false path. paths will att empt to travel through the corresponding gadget. we have argued in the above claim that in this ca se it is possible to visit every vertex in the gadget exactly once. because of the way in which these vertices are joined together. until reaching xe. ): Suppose that F has a satisfying assignment. and then it will continue with x2 . We assert that the form of the path mu st be essentially the same as the one described in the previous part of this proof. x2 = 1. x3 = 0. and the lower figure shows the no n-Hamiltonian path resulting from the nonsatisfying assignment x1 = 0. 2. or 3 of its literals will be true. In particular. . either 1. we know that for each clause. implying that G has a Hamiltonian path. and so on. or 3. respectively. then will travel along either the true path or false pat h for x1. (: Suppose that G has a Hamiltonian path. However. The upper figure shows the Ha miltonian path resulting from the satisfying assignment. depending on whether it is 1 or 0. Such a path will visit each variable vertex exactly once. Also observe that for each variable vertex. This means that for each clause.3 to to F T T Start here to to F T F Start here 1 3 3 x2 e x1 x3 x2 x2 x2 x3 x x x1 x3 x2 x1 x2 x1 x2 x3 x2 e Fig. in the assignment. then x3. 2. x1 = 1. 81: Correctness of the 3SAT to DHP reduction. either 1. Thus every vertex in the graph is visit ed exactly once. Because this is a satisfying assignment. This path will start at the variable vertex x1. x3 = 0. x2 = 1.