documenth2

16
Amit Shekhar ID: 108266469 NetID: ashekhar CSE 548 – Analysis of Algorithms Solution to Assignment #2 Due Thursday, October 27, 2011 Discussed at Office hours and with Ayon Chakraborty and Amit Arya

Upload: amit-shekhar

Post on 16-Oct-2014

445 views

Category:

Documents


13 download

TRANSCRIPT

Page 1: Documenth2

Amit Shekhar

ID: 108266469

NetID: ashekhar

CSE 548 – Analysis of Algorithms

Solution to Assignment #2

Due Thursday, October 27, 2011

Discussed at Office hours and with Ayon Chakraborty and Amit Arya

Page 2: Documenth2

Problem 1

In class we saw how to construct circuits for addition of two n-bit numbers that have depth of

O(log n) and O(1). In this problem we look at how to design circuits for multiplying.

Note: You may assume that the size of an addition circuit (both for standard and nonunique

representation) is Θ(n).

(a) Design a naıve circuit that has depth O(log2 n). What is the size of this circuit? Explain

how to compute the size.

Solution:

From the class, we establish that circuit for Addition of two n-bit numbers has depth of log n

using standard representation.

The recurrence relations for n-bit addition:

Depth: T (n) = T (n2 ) + 1 =⇒ O(log n)

Size: S(n) = 3S(n2 ) + n

=⇒ (32)logn ∗ n=⇒ O(nlog 3)

where n is the task done at Multiplexer and 3 came from the decision to compute more significant

half twice. Once when Cn2

= 1 and another time when Cn2

= 0

Here, we seek multiplication of two n-bit numbers, which is definitely an addition of n numbers

of 2n bits each. This is an adaptation of the simple mathematical multiplication. Here is how

it is so. The length of each number becomes 2n because after each bit is multiplied with the

multiplicand, the resultant (intermediate) number is shifted towards left by one bit. Since we are

multiplying n bits, we must have shifted one of the intermediate result to n bits to the left. Thereby,

making the length of each number to be added to 2n. Please note the extra bits can be padded.

Note that we have already established that circuit for Addition of two n-bit numbers has depth

of (log n)

Method:

Now we take each intermediate result in pair and add them.

repeat this process till we get the final value. This is analogous to MERGE part of a divide

and conquer algorithm. This gives the depth of circuit is log n for this part.

Hence, the depth of entire circuit becomes O(log2 n)

Size Computation:

Page 3: Documenth2

If we assume O(nlog 3) to be equal to Θ(n) then Size would be O(n2) as there can be n nodes

for the tree shown. Each such node requires Θ(n) of circuit size.

(b) Design a better circuit that has depth O(log n). What is the size of this circuit? Explain

how to compute the size.

Solution:

From the class, we establish that circuit for Addition of two n-bit numbers has constant depth

using Non Unique representation.

The recurrence relations for n-bit addition:

Depth: T (n) = O(1)

Size: T (n) = O(n)

Here, we seek multiplication of two n-bit numbers, which is definitely an addition of n numbers

of 2n bits each. This is an adaptation of the simple mathematical multiplication. Here is how

it is so. The length of each number becomes 2n because after each bit is multiplied with the

multiplicand, the resultant (intermediate) number is shifted towards left by one bit. Since we are

multiplying n bits, we must have shifted one of the intermediate result to n bits to the left. Thereby,

making the length of each number to be added to 2n. Please note the extra bits can be padded.

we have already established that circuit for Addition of two n-bit numbers has constant depth.

Method:

Now we take each intermediate result in pair and add them. and repeat this process till we get

the final value. This is analogous to MERGE part of a divide and conquer algorithm. This gives

the depth of circuit is log n for this part.

Hence, the depth of entire circuit becomes O(log n)

Size Computation: for n nodes once again we get the circuit size as O(n2)

Page 4: Documenth2

Problem 2

In this problem, we continue working on multiplication circuits. The objective is to reduce the

overall size of the multiplication circuits to something that is o(n2).

Hint: please use Problem 5 of Problem Set 1 as a guide.

(a) Please describe your construction algorithm and describe the depth of the circuit.

Solution:

The number can be written as: X = 2ma+ b and Y = 2mc+ d

Multiplication requires:

Z = 22mac+ 2m(bc+ ad) + bd

We see that (bc+ ad) can be represented by (a+ b)(c+ d)− (ac+ bd). This reduces the

number of multiplication circuit by 1. As multiplication can be performed by using circuits that

can perform multiplication of (a+ b)(c+ d), ac, bd only.

The image below shows the abstracted circuit of multiplication in this way:

(b) What is the recurrence relation for the size of your circuit?

Solution:

The recurrence relation:

T (n) = 3T (n2 ) +O(n)

(c) Please solve this recurrence relation.

Solution:

From Recursion Tree:

Work at level 1⇒ n

Work at level 2⇒ 31 × n21

......

Work at level n⇒ 3n × n2n

Page 5: Documenth2

Depth of the tree = log2 n

Therefore, total work = Σn× (32)i ∀ i = 0 . . . log2 n

The terms are in Increasing geometric series hence, the last term would dominate. This also

means contribution from leaves will dominate. At the leaf level contribution is T (1) = Θ(1) (by

each leaf).

The number of leaves is 3log2 n ⇒ nlog2 3

Therefore, T (n) = Θ(nlog2 3)

Alternatively,

This recurrence relation falls under case 1 of Master Theorem

where T (n) = aT (nb ) + f(n)

with a = 3, b = 2, ε = 1, and f(n) = n

The solution is: T (n) = O(nlogb a)

= O(nlog2 3)

Page 6: Documenth2

Problem 3

Imagine an infinitely large array A[0 . . .∞]. In this array,

A[0] = A[1] = . . . = A[n− 1] = 0,

and

A[n] = A[n+ 1] = A[n+ 2] = . . . = 1.

That is, the first n elements of the array are 0 and all subsequent elements are 1. In constant

time we can query the array to find the value of an array element A[i].

We do not know the value of n, the index of the first nonzero element.

A = 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1 . . .

(1) Describe an algorithm to find the value of n. This algorithm should make at most O(log n)

queries.

Solution:

We query elements whose index is given by 2i where i ranges from 0 . . . log n. Here, it’s possible

that we may bump into the part where there are only 1s. In that case, we should return back

to immediately previous point [the index at 2(logn − 1) in the array] and then we should start

repeating above thing from that index till we reach the first 1.

Please note that first occurrence of 1 is at 2(i− 1) < n < 2i and i = log n

At max O(log n) queries.

(2) Describe an algorithm for finding any index m, where A[m] = 1 and m < nc for some constant

c > 1. Show that this algorithm requires O(log log n) array queries.

Solution:

we solve this problem in the same way as above except that we move forward in the array at a

step of 2(2i) where ranges from 0 . . . log log n

Proof for the number of queries required:

Here, we step by 22i

to reach to the part where there are all 1s. Hence, to reach n we step

log logn and query at each step whether we have reached at the required place.

(3) Describe an algorithm for finding any m, where A[m] = 1. How fast can you make this

algorithm?

Solution:

Once again, we can go forward to raise the step. The step can be any suitable 2222

i

based upon

infiniteness of the size of array. Note that the level of step can be chosen based upon the value of

n. If at all, it approaches to infinity then we can increase the step value to a big number. We can

do this in O(log ∗ n) and some constant time where we return back and check for the first 1.

Page 7: Documenth2

Problem 4

Consider the knapsack problem discussed in class: For set S = {s1, s2, · · · , sn} of integers and

target integer K, is there a subset T ⊆ S, such that∑ti∈T

ti = K?

(1) Recall the algorithm from class. Provide the subproblems, then present pseudocode from class.

Solution:

Sub problem:

For every possible value of target integer K, we are going to check what subset of S can fit in

properly. In order to check for any intermediate K from 0 . . .K we try the entire set S. Though,

DP technique helps us to compute most of the bigger values using solution to smaller subproblem.

for all k = 0 . . .K

for all i = 1 . . . N

Knapsack problem for set {s1, s2, · · · , si}Pseudocode:

Initialization:

for all k = 0 . . .K

B[0, k] = 0

B[0, 0] = 0

Loop Assignment:

for all i = 1 . . . N

for all k = 0 . . .K

B[i, k] = B[i− 1, k]⋃B[i− 1, k − si]

Goal Cell:

Return B[n, k]

(2) The algorithm from (1) only answers the question with a yes or no. What part of the algorithm

would we modify so that we can compute the set T? What are the modifications?

Solution:

Pseudocode:

Initialization:

for all k = 0 . . .K

B[0, k] = 0

TAB[0, k] = 0 ¡— table for encoding regions

for all i = 0 . . . n

TAB[i, 0] = 0

Page 8: Documenth2

B[0, 0] = 0

for all i = 1 . . . N

for all k = 0 . . .K

if(B[i− 1, k − si] > B[i− 1, k])

B[i, k] = B[i− 1, k − si]TAB[i, k] = 1

else

B[i, k] = B[i− 1, k]

TAB[i, k] = 0

The construction of subset from the Tab Matrix.

for all i = n . . . 1

if(TAB[i,K] == 1)

Print i th element from set.

K = K − siReturn B[n, k]

Page 9: Documenth2

Problem 5 Problem from Steve Skiena

Consider the problem of storing n books on shelves in a library. The order of the books is fixed

by the cataloging system and so cannot be rearraged. Therefore, we can speak of a book bi, where

1 ≤ i ≤ n, that has a thickness ti and height hi. The length of each bookshelf at this library is L.

Suppose all the books have the same height h (i.e. h = hi = hj for all i, j) and the shelves are

all separated by a distance of greater than h, so any book fits on any shelf. The greedy algorithm

would fill the first shelf with as many books as we can until we get the smallest i such that bi does

not fit, and then repeat with subsequent shelves. Show that the greedy algorithm always finds the

optimal shelf placement, and analyze the time complexity.

Solution:

Problem : Show that the greedy algorithm always finds the optimal shelf placement

Proof by contradiction.

There are n books to be stored. Book bi has a thickness ti, where 1 ≤ i ≤ n, . All the books

have the same height h (i.e. h = hi = hj for all i, j). The length of each book shelf at the library is

L and the shelves are all separated by a distance of greater than h, so any book fits on any shelf.

Assume, there exists an optimal way other than greedy, and we can arrange the books such

that more number of books fit in a shelf. This infers, there should be some space left by the greedy

method because height is constant and order of books cannot be changed. So, even the alternate

solution ends up filling the first shelf with as many books as it can until it get the smallest i such

that bi does not fit, and then repeat with subsequent shelves. Again because of the condition that

height is constant and order of books cannot be changed.

Hence we conclude that greedy method is the same as the alternate optimal one.

The Recurrence relations is as follows :

T(n) =

= T (n− 1) + c

= (T (n− 2) + c) + c

= ((T (n− 3) + c) + c) + c...

= T (n− k) + k ∗ cT (n) is constant for n = 1 after a depth of n− 1.

Hence, the running time = O(n)

Page 10: Documenth2

Problem 6 Problem from Steve Skiena

This is a generalization of the previous problem. Now consider the case where the height of the

books is not constant, but we have the freedom to adjust the height of each shelf to that of the

tallest book on the shelf. Thus the cost of a particular layout is the sum of the heights of the largest

book on each shelf.

(1) Give an example to show that the greedy algorithm of stuffing each shelf as full as possible does

not always give the minimum overall height.

Solution:

Consider books a,b,c,d having widths 3,6,3,6,3 and heights 11,14,17,5,6 respectively. Let the

width of the shelf be 13. In such a case, the Greedy Algorithm will order the books as:

Shelf 1: a, b → max height = 14

Shelf 2: c, d → max height = 17

Shelf 3: e → max height = 6

Shelf height will be = 37.

However, if we order the books as:

Shelf 1: a max height = 11

Shelf 2: b, c max height = 17

Shelf 2: d, e max height = 6

Hence, total height of all shelves = 34, which is better than the answer given by Greedy

Algorithm.

Thus, Greedy Algorithm does not always give optimal solution for minimizing the overall height

of the shelves.

(2) What technique should we use to solve this problem?

Solution:

Using Technique of dynamic programming, we can solve this problem.

(3) What are the subproblems?

Solution:

For a height, all the books that can fit in one self. Here, a possible set can start anywhere in

the list of books.

So, a subproblem may contain a list of books bi, bi + 1 . . . bj∀i < jandi, j ∈ n(4) How many subproblems are there?

Solution:

Upper limit for the number of subproblems can be nL. For every Shelf, we may have n sub

problems.

(5) Give an algorithm for this problem, and analyze its time complexity.

Solution:

Pseudo code:

Initialize:

OPT[][] be the DP memoization matrix initialized with a large value.

Loop and sub problem solving using the previously solved smaller problem

Page 11: Documenth2

for all l = 0 . . . L

for all k = 1 . . . n− 1

if ((summation of thickness of all books from k . . . k+ l) ≤ Book Shelf length)

OPT [k, k + l] = max{OPT (k, k + l − 1), hk+l}else

Current subproblem doesn’t fit in. OPT [k, k + l] = very large value.

Goal Cell:

OPT [1, n]

Time complexity O(nL)

Page 12: Documenth2

Problem 7

Suppose you are given three strings of characters: X, Y, and Z, where

|X| = n, |Y| = m, and |Z| = n+m.

Z is said to be a shuffle of X and Y iff Z can be formed by interleaving the characters from X and

Y in a way that maintains the left-to-right ordering of the characters from each string.

(a) Show that cchocohilaptes is a shuffle of chocolate and chips, but chocochilatspe is not.

Solution:

(b) Give an efficient dynamic-programming algorithm that determines whether Z is a shuffle of X

and Y.

Solution:

When we try to make the underlying DAG (Directed acyclic Graph) here, we see that each node is

being approached from either of the two ways. For any (i, j)th element it is reachable either from

(i, j − 1)th node or (i− 1, j)th node. If we start traversing from (0, 0) to the end (m,n) by above

mentioned ways and we actually reach to the end without violating any rule, then we’re done and

the 3rd string is a shuffle. Otherwise, the 3rd string is not a Shuffle.

Pseudo code:

A is the matrix that stores solution to previously computed smaller subproblems

for all i = 0 . . .M and j = 0 . . . N

if (X[i] == Z[i+ j])

A[i][j] = A[i][j − 1]

i← 1 + 1

else if (Y [j] == Z[i+ j])

A[i][j] = A[i− 1][j]

j ← j + 1

else

Return NOT A SHUFFLE!

Return A SHUFFLE!

Hint: The values the dynamic programming matrix you construct should be Boolean, not numeric.

Page 13: Documenth2

Problem 8 Fun, challenging problem

There are N soldiers lined up, about to execute a hapless prisoner. The lieutenant, who begins

the firing process, is located at one end of the line. The soldiers all want to fire simultaneously.

Unfortunately, the soldiers can only talk to their immediate neighbors on the left and right. In

addition, these soldiers are not very intelligent and only have constant memory , independent of N .

Notice that constant memory is very little. It is not enough even to count up to N ; this requires

log(n) bits. It is not enough to have a name, because unique names also require log(n) bits.

Devise an algorithm that allows these soldiers to fire in unison. The algorithm should have running

time O(n).

Solution:

Here, the soldiers can only talk to their immediate neighbors on the left and right. This fact

gives us a way to solve. And we must devise a way such that everyone gets to hear the signal before

shooting. Every time, a soldier at the left most position can definitely talk with someone in the

mid of the row.

Firstly, devise a way how a soldier can talk to another soldier that is in the middle of the row

i.e, how to identify mid of the row. Here we can use basic reflection property. Say, soldier on the

left sends two signals towards right. One of the signal travels 3x faster than another. So, when the

slower signal reaches the mid, faster signal must also be reaching the mid point after traveling to

the end. So, this gives us the mid point for any row of any length.

Now, In order to enable everyone to signal we must start with the communication with first

element on the left and the mid of the row. The above mechanism can be employed to do this.

Next, we have two sub-list of equal size – Divided by the mid that we found just now. Now, by

treating the new sub-arrays the same way as we did to the original row we can make communication

happen between 1st soldier on the left and the soldier standing in the mid of 1st sub-array. When

we do it recursively to the end when each soldier talks to only its neighbor, we are in a position to

make each soldier talk in Unison.

Now the running cost analysis:

The first level communication requires 2n time

The next level communication requires 2n2 time

...

The subsequent level communication requires 2n2l

time

Hence the total work required still remains linear i.e, O(n)

Page 14: Documenth2

Note that they move and interact at exactly the same speed; i.e., they are synchronized. Hint: Use

divide and conquer. You should assume soldiers all operate at the same speed.

Page 15: Documenth2

Problem 9

In class we saw how to analyze divide and conquer matrix multiplication of two N ×N matrices.

Now we’ll show how to lay out the matrix to optimize for memory transfers (both using blocking

and divide and conquer). We’ll use the same DAM model that we described in class and in the last

problem set.

(a) Suppose that we divide the matrix into blocks of size B (i.e.,√B by

√B). Prove that we

can achieve O(N3/B3/2) memory transfers for a multiplication.

Solution:

The recurrence relation for the following method is:

T (n) = 8T (n2 ) +O(n2)

Solving the above recurrence relation, we get

T(n) = O(n3)

Now, a Block of size B can hold (√B ∗√B) elements. And a block B can be considered now

as a square sub matrix.

For a matrix of size N ∗N , there can be (N2

B ) such blocks as B is the unit of transfer and the

counting transfers. This also infers that the N ∗ N matrix can now be considered as ( N√B∗ N√

B)

square matrix. Therefore, as per our solution to the recurrence relation, the required number of

multiplication will be: ( N√B

)3.

In Big Oh notation it’ll be O( N3

B32

)

(b) Suppose that we divide the matrix into blocks of size M (i.e.,√M by

√M). Prove that we

can achieve O(N3/B√M) memory transfers for a multiplication.

Solution:

Here, a Block of size M can hold (√M ∗

√M) elements. And the total number of multiplication

will be ( N√M

)3

For each (√M ∗

√M) elements there will be M

B blocks. And the memory transfers will be

O(( N√M

)3 ∗ MB )

Upon simplification this becomes: O( N3

B∗√M

)

Page 16: Documenth2

Problem 10 (challenging problem, but good practice for understanding divide and conquer well)

Now let’s explore divide and conquer solutions for matrix multiplication (as we discussed in

class). We want to multiply A and B (each of size N ×N) and the product will be stored in C:

A =

[A1 A2

A3 A4

]B =

[B1 B2

B3 B4

]C =

[C1 C2

C3 C4

]The divide and conquer solution from class is:[

A1 A2

A3 A4

] [B1 B2

B3 B4

]=

[A1B1 +A2B3 A1B2 +A2B4

A3B1 +A4B3 A3B2 +A4B4

]

To ensure good memory locality, we’ll store the matrix in the same divide and conquer order, e.g.,

A1, A2, A3, A4. Thus the matrix is stored in a zig-zag manner in memory.

(a) What is the recursion relation for the cost of a multiplication?

Solution:

The recurrence relation for the cost of multiplication:

T (n) = 8T (n2 ) +O(n2)

(b) Solve the recursion relation and prove that the divide-and-conquer multiplication achieves

O(N3/B√M) memory transfers.

Solution:

Solving the recurrence relation, we get

T(n) = O(n3)

Proof:

Now, a Block of size B can hold (√B ∗√B) elements. And a block B can be considered now

as a square sub matrix.

For a matrix of size N ∗N , there can be (N2

B ) such blocks as B is the unit of transfer and the

counting transfers. This also infers that the N ∗ N matrix can now be considered as ( N√B∗ N√

B)

square matrix. Therefore, as per our solution to the recurrence relation, the required number of

multiplication will be: ( N√B

)3. In Big Oh notation it’ll be O( N3

B32

)

Similarly, a Block of size M can hold (√M ∗

√M) elements. And the total number of multi-

plication will be ( N√M

)3 For each (√M ∗

√M) elements there will be M

B blocks. And the memory

transfers will be O(( N√M

)3 ∗ MB )

Upon simplification this becomes: O( N3

B∗√M

)