33
Divide and conquer recurrence formulas Problem: Assuming that single-bit operations cost unit time, how long would it take to compute the square of a n bit integer? 101100110 101100110 1011001100 101100110 101100110 101100110

Divide and conquer recurrence formulas Problem: Assuming that single-bit operations cost unit time,…

Embed Size (px)

DESCRIPTION

m 2 = (p 2. 2 n + 2 n/2. [(p + q) 2 - p 2 - q 2 ] + q 2 ) Karatsuba’s algorithm: Input: m with n bits. 1. If m has one bit, then output the answer directly and halt. 2. Let p = most significant n/2 bits of m, q = least significant n/2 bits. 3. Recursively compute ps = p 2 and qs = q Compute r = p+q, and recursively compute ss = r Output shift(ps,n) + shift(ss - ps - qs, n/2) + qs

Citation preview

Page 1: Divide and conquer recurrence formulas Problem: Assuming that single-bit operations cost unit time,…

Divide and conquer recurrence formulas Problem: Assuming that single-bit operations cost unit time, how long would it take to compute the square of a n bit integer?

101100110 101100110 1011001100 101100110 101100110 101100110 101100110

Page 2: Divide and conquer recurrence formulas Problem: Assuming that single-bit operations cost unit time,…

This school method of multiplication requiresO(n2) bit-level operations. Why? Essentially, we need to multiply each bit of the number by every bit. Karatsuba’s algorithm: m = p . 2n/2 + qSo, m2 = (p . 2n/2 + q )2

= (p2 . 2n + 2n/2 . 2 p q + q2) 2 p q = (p + q)2 - p2 - q2, so

m2 = (p2 . 2n + 2n/2 . [(p + q)2 - p2 - q2 ] + q2)

Page 3: Divide and conquer recurrence formulas Problem: Assuming that single-bit operations cost unit time,…

m2 = (p2 . 2n + 2n/2 . [(p + q)2 - p2 - q2 ] + q2)

Karatsuba’s algorithm: Input: m with n bits.1. If m has one bit, then output the answer directly and halt.2. Let p = most significant n/2 bits of m, q = least significant n/2 bits. 3. Recursively compute ps = p2 and qs = q2.4. Compute r = p+q, and recursively compute ss = r2.5. Output shift(ps,n) + shift(ss - ps - qs, n/2) + qs

Page 4: Divide and conquer recurrence formulas Problem: Assuming that single-bit operations cost unit time,…

Analysis of Karatsuba’s algorithm:• shift(p,n) costs O(n) bit operations.• Adding two n bit integers takes O(n) bit operations.• Subtracting a n bit integer from a n bit integer takes O(n) operations.1. If m has one bit, then ...2. Let p = most significant n/2 bits of m, q = least significant n/2 bits. O(n) 3. Recursively compute ps = p2 and qs = q2. 2 T(n/2)4. Compute r = p+q, and recursively compute ss = r2. O(n) + T(n/2)5. Output shift(ps,n) + shift(ss - ps - qs, n/2) + qs O(n)

Page 5: Divide and conquer recurrence formulas Problem: Assuming that single-bit operations cost unit time,…

Recurrence formula T(n) = 3 T(n/2) + O(n)Solution: T(n) = O(n1.59)The textbook gives a master theorem to handle a general type of divide-and-conquer recurrence formula T(n) = a T(n/b) + f(n) (a>= 1, b > 1)• Problem is divided into a sub-problems each of size n/b and each recursively solved.• Overhead f(n) to combine the sub-problem results.

Page 6: Divide and conquer recurrence formulas Problem: Assuming that single-bit operations cost unit time,…

There are three cases to consider. (1) f(n) = O(nlog

b a - ) for some

constant > 0. Then, T(n) = (nlog

b a).

(2) f(n) = (nlogb

a). Then, T(n) = (nlog

b a lg n).

(3) f(n) = (nlogb

a + ) for some constant > 0, and if a f(n/b) <= c f(n) for some constant c < 1, and for all large enough n, then T(n) = (f(n)). Previous example belongs to case (1) where a = 3 and b = 2.

Page 7: Divide and conquer recurrence formulas Problem: Assuming that single-bit operations cost unit time,…

We will now consider examples for other cases.Merge Sorting. To sort an array of n elements, recursively sort two halves, and merge. T(n) = 2 T(n/2) + O(n).Solution: T(n) = (n log n)Heap building. Convert an array of n keys into a heap. Question: What is the definition of a heap?For all i= 1,2,..., n, A[i] >= A[i/2]. (Assume A[0] is -maxint.)

Page 8: Divide and conquer recurrence formulas Problem: Assuming that single-bit operations cost unit time,…

Heap Sort: Based on a clever data structure called a heap.A heap is an array in which the keys will always be stored in index 1 to k for some k. Such an array is called a heap if when you view the heap as a full binary tree, the parent key is always <= the child key.

3

87

47

1

2 3

4 5

A 1 2 3 4 5 3 7 4 7 8

class Heap { int[] HeapElements; int Size}

Page 9: Divide and conquer recurrence formulas Problem: Assuming that single-bit operations cost unit time,…

An obvious but important fact: HeapElements[1] contains the smallest key.Heap can support the following three operations very fast, i.e. in time O(log n) where n is the size of the heap.• void Insert(int x) • int DeleteMin( ) Informal description of the algorithm for Insert(x):• Find a place for x along the path from the leaf with index =Size/2 and the root (index = 1).

Page 10: Divide and conquer recurrence formulas Problem: Assuming that single-bit operations cost unit time,…

More formal description: Size++; for (int j=Size; HeapElements[j/2] > x; j/=2) HeapElements[j]=HeapElements[j/2]; HeapElements[j] = x; Although the code is extremely simple, it is tricky.Test it with some examples. What happens if the key inserted is the smallest?

Page 11: Divide and conquer recurrence formulas Problem: Assuming that single-bit operations cost unit time,…

First consider Max-Heapify. Problem is to convert the tree rooted at node i into a heap given that trees rooted at 2i and 2i+1 are heaps.

k

L R

i

Algorithm is given in page 130 of the text.Suppose H[2i] = x, H[2i+1]= y.Case 1: (k < x) && (k < y) In this case, the tree rooted at is a heap. So, the procedure terminates.

?

Page 12: Divide and conquer recurrence formulas Problem: Assuming that single-bit operations cost unit time,…

Case 2: (k > x) && (y > x). Thus, x is the minimum of the three keys k, x and y. Suppose we swap the keys k and x. Now the problem reduces to Adjust(2i). Case 3: y = min {k, x, y}. In this case, swap k and y; Adjust(2i+1).

Number of comparisons performed by Max-Heapify is 2 h where h is the height of the heap. Since the heap is a complete binary tree, h is at most [log n]+1, so overall cost of Heapify is O(log n).

Page 13: Divide and conquer recurrence formulas Problem: Assuming that single-bit operations cost unit time,…

Build-Max-Heap. To convert a tree rooted at node i into a heap, recursively convert trees rooted at 2i and at 2i+1 into heaps, then heapify.

Build-Max-Heap(A, i, n) { if (2*i > n) return; Build-Max-Heap(A, 2*i, n); Build-Max-Heap(A, 2*i+1,n); Heapify(A,i,n); }

Analysis: T(n) = 2 T(n/2) + O(log n).Solution (by case 3 of master theorem) T(n) = O(n).Note: The algorithm in the text is the iterative version of the above algorithm.

Page 14: Divide and conquer recurrence formulas Problem: Assuming that single-bit operations cost unit time,…

Review of sortingWorst-case Quadratic time sorting algorithms

• bubble-sort• selection-sort• insertion-sort• quick-sort

Worst-case O(n log n) algorithms• heap-sort• merge-sort

Average-case O(n log n) algorithms• heap sort, merge-sort• quick-sort

Intermediate (and hard to analyze) algorithm

• shell-sort (best: O(n (log n)2 )

Page 15: Divide and conquer recurrence formulas Problem: Assuming that single-bit operations cost unit time,…

Quicksort - Expected case analysis. Quicksort(A, low, high) // sort the segment A[low ... high] // k is a constant to be determined experimentally. { if (high == low + 1) return; if (high - low <= k) call insertion sort to sort;

k = partition(A, low, high, pivot); Quicksort(A, low, k-1); Quicksort(A, k+1, high); } If pivot splits the array into sizes i and n-i-1,then cost of recursive calls - T(i) and T(n-i-1).Cost of partition step is n.

Page 16: Divide and conquer recurrence formulas Problem: Assuming that single-bit operations cost unit time,…

split = (0, n-1) -> T(0) + T(n-1)split = (1, n-2) -> T(1) + T(n-2) . . . . . . . . . . . . . . . . . . . . . . . . .Split = (n-1, 0) -> T(n-1) + T(0)Crucial fact: all these cases are equally likely when averaged over all inputs.So, we get the recurrence formula:

)}0()1(...)2()1()1()0({11)( TnTnTTnTTn

nnT

Solution to the equation is T(n) = O(n log n)Text uses induction to prove this. Alternative approach is presented next.

Page 17: Divide and conquer recurrence formulas Problem: Assuming that single-bit operations cost unit time,…

)}0()1(...)2()1()1()0({11)( TnTnTTnTTn

nnT

n T(n) = n(n-1) + 2{T(0) +T(1) + ... + T(n-1)}(n+1) T(n+1) = (n+1)n + 2{ T(0) + T(1) + ... +T(n)}

(n+1) T(n+1) - n T(n) = 2n + 2 T(n)(n+1) T(n+1) - (n+2) T(n) = 2n

)2)(1(2

1)(

2)1(

nnn

nnT

nnT

It follows that T(n) = O(n log n).

Page 18: Divide and conquer recurrence formulas Problem: Assuming that single-bit operations cost unit time,…

Indicator variable method

Example: N people leave their hats at the front desk of a bar. When the leave, each one is given a hat at random. What is the expected number of people who receive their own hat?

Define Xi = 1 if I receives his/her hat, 0 else.E(Xi) = 1* p( i receives his/her hat) + 0 * p( i does not receive his/her hat) = 1/n.X = X1 + …+ Xn is the random variable that represents the number of people receiving their hat.E(X) = E(X1) + …+ E(Xn) = 1/n * n = 1

Page 19: Divide and conquer recurrence formulas Problem: Assuming that single-bit operations cost unit time,…

Alternative Derivation based on indicator variable method

Lemma 7.1. (page 156) : Let X be the number of comparisons performed by the Partition step (shown high-lighted below) on an n-element array. Then the running time of Quicksort is O(n+X).

Quicksort(A, low, high) // sort the segment A[low ... high] // k is a constant to be determined experimentally. { if (high == low + 1) return; if (high - low <= k) call insertion sort to sort;

k = partition(A, low, high, pivot); Quicksort(A, low, k-1); Quicksort(A, k+1, high); }

Page 20: Divide and conquer recurrence formulas Problem: Assuming that single-bit operations cost unit time,…

In fact, if we only count comparisons, then the entire cost of Quicksort resides in calls to Partition.

Let A = z1, …, zn where zi is the i-th smallest element of A. Also define Zij = {zi, …, zj}When does the algorithm compare zi and zj?First, note that a pair of keys will be compared at most once by Quicksort algorithm. Why?Define Xij = 1 if zi and zj are compared, 0 else.Clearly, E(X) = ijXij

So we first need to estimate E(Xij). Xij is given by 2/(j-i+1) from which it follows that E(X) = (log n). Read page 158 of the text for details.

Page 21: Divide and conquer recurrence formulas Problem: Assuming that single-bit operations cost unit time,…

Searching• Dictionary problem

• search, insert and delete operations• findmin, deletemin, rangesearch, successor• merge, split

• Search tree• pointer-based• cost of search, insert, delete = O(h)

• Balanced search tree• to insure h = O(log |S|), S = size of tree.• worst-case (deterministic) AVL, red-black• amortized: splay tree• worst-case (randomized) treap

Page 22: Divide and conquer recurrence formulas Problem: Assuming that single-bit operations cost unit time,…

Searching - hash table• array-based.• Store key x in location h(x) where h maps keys to an index of table.• Typically, |U| >> |T| >> |S| where

• U = set of all possible keys• T = hash table• S = set of keys actually present

• since |U| >> |T|, collisions can and will happen.• Chaining uses a linked list to chain colliding keys.• Open addressing uses rehashing using a collection of hash functions.

Page 23: Divide and conquer recurrence formulas Problem: Assuming that single-bit operations cost unit time,…

Cost of searching• Chaining: Let m = table size and n = number of keys to be stored. Assuming uniform hashing, cost of both successful and unsuccessful searching is where = n/m, load factor.• Open addressingAssuming uniform hashing, cost of unsuccessful search is 1/(1- ). The cost of successful search is 1/ ln(1/(1- )).• Applications

Page 24: Divide and conquer recurrence formulas Problem: Assuming that single-bit operations cost unit time,…

Standard design techniques Divide and conquer• merge-sorting, binary search, Karatsuba• Fast Fourier Transform to multiply polynomials p(x) and q(x), both of degree n-1. (has n coefficients.)

1) evaluate p(x) and q(x) at carefully chosen 2n (complex) numbers c1,..., c2n.2) product polynomial r(x)’s value is known at c1,..., c2n. r(cj) = p(cj) * q(cj)3) from these values, interpolate the polynomial back.

Step (2) is Fourier transform and (3) is inverse Fourier transform.

Page 25: Divide and conquer recurrence formulas Problem: Assuming that single-bit operations cost unit time,…

Dynamic programming Main idea: typically, solving a problem using a standard data structure (e.g. array) involves solving sub-problems on the same data structure (e.g. sub-tree). If the same instance is needed more than once, simply use a table to store the result, instead of making multiple recursive calls to the same instance. (often, this results in a non-recursive version.)

• longest common subsequence• optimal matrix chain product• knapsack problem• a simple two-person game

Page 26: Divide and conquer recurrence formulas Problem: Assuming that single-bit operations cost unit time,…

Recall the recurrence formula for f(n), the number of ways to place three types of dominos in a 2 by n board.f(n) = g(n) + f(n-1) + g(n-1) + f(n-2)g(n) = g(n-1) + f(n-1)Here is a direct conversion of this formula into program segments to compute f and g:

void f(int n){if (n == 1) return 2 else if (n==2) return 6 else return g(n) + f(n-1) + g(n-1) +f(n-2)}

Page 27: Divide and conquer recurrence formulas Problem: Assuming that single-bit operations cost unit time,…

This is very inefficient. Why?Redundant calls.f(n) = g(n) + f(n-1) + g(n-1) + f(n-2)g(n) = g(n-1) + f(n-1)• To compute f(n), g(.) is called with argument n, which in turn calls f(.) with argument n-1. Then, after completing g(n), f calls itself with n-1, thus computing f(n-1) twice. • This redundancy doubles after each call, leading to exponential time to compute f(n).• Instead, simply use arrays F and G to store f(i) and g(i) as they are computed.

Page 28: Divide and conquer recurrence formulas Problem: Assuming that single-bit operations cost unit time,…

A problem from Olympiad on Informatics

An arbitrary list of integers (both positive and negative) is presented to two players A and B with A playing first. In their turn, either player is allowed to pick the first or last number from the (remaining) list, and the number is deleted from the list. As usual, players take turns. When the list turns empty, the game ends. The player with higher total wins. The problem is to design an algorithm to determine for a given input list if the first player can force a win (against any opponent).

Page 29: Divide and conquer recurrence formulas Problem: Assuming that single-bit operations cost unit time,…

Example: < 1 -8 -2 4 > Player 1 chooses 4. Player 2 chooses 1. Player 1 chooses -2. Player 2 chooses -8. Player 1 wins. Decision tree representation of possibilities:

Page 30: Divide and conquer recurrence formulas Problem: Assuming that single-bit operations cost unit time,…

Observations:• All leaves are at the same level in the game tree.• To determine the best strategy for player 1, start at the rootand recursively evaluate the two subtrees and choose the maximum of the two.• However, when you expand a subtree rooted at a node whichcorresponds to second player choice, the rule is to choose the minimum of the values of the subtrees.

Player 1

Player 2 Player 2

Input: a1 a

2 … a

n

a1

an

a2 ..

an

a1 ..

an-1

a2

an

a1 a

n-1

a3 ..

an

a2 ..

an-1

Page 31: Divide and conquer recurrence formulas Problem: Assuming that single-bit operations cost unit time,…

algorithm Play( A[ ], m, n)// returns the maximum score player 1 can get when playing with the list < A[m] , A[m+1], …, A[n] >{ if (n-m == 1) max {A[m], A[n]} else return max { Play(A, m+2, n) + A[m], Play(A, m+1, n-1) + A[m], Play(A, m+1,n-1) + A[n], Play(A, m, n-2) + A[n] } }

Page 32: Divide and conquer recurrence formulas Problem: Assuming that single-bit operations cost unit time,…

Complexity of the algorithm: Main operations: key comparisons,+, function calls. Since function calls are the most expensive,we may just focus on it. T(n) = 4 T(n-2) + c with T(2) = 2. Solution: ? ? ?

Can we improve the algorithm? Yes, look at the 4 sub-problems two levels down from the root.Of the 4 sub-problems, only three are distinct. So, we just skip one of the two calls.

Page 33: Divide and conquer recurrence formulas Problem: Assuming that single-bit operations cost unit time,…

Complexity of the resulting algorithm: T(n) = 3 T(n-2) + c with T(2) = 1.• We can significantly improve this solution by dynamic programming.• Instead of making recursive calls, simply use “table look-up”. • A two-dimensional array R[ , ] will be used to store the result of Play(A, m, n).