ClassS04CS141/Hwk3Soln

ClassS04CS141 | ClassS04CS141 | recent changes | Preferences

Hwk3 solutions

Answers are in italics.

1. Consider the following algorithm:

 1.  HashTable<int,bool> visited(0);
 2.  HashTable<int,int> M(0);
 3.  
 4. int mystery(Digraph G, int vid) {
 5.   if (! visited[vid])  {
 6.       visited[vid] = 1;
 7.       M[vid] = vid;
 8.       Array<int> out_nbrs = G.out_nbrs(vid);
 9.       for (int i = 0;   i < out_nbrs.size();  ++i) {
 10.        int P = mystery(G, out_nbrs[i]);
 11.        if (P > M[vid])  M[vid] = P;
 12.     }
 13.  }
 14.  return M[vid];
 15.}

Here is an example graph, too:

vertex set = {1, 2, 3, 4, 5, 6, 7, 8, 9}
directed edges = { (1,2), (1,3), (2,4), (2,5), (4,7), (4,8), (3,6), (3,7), (2,6), (1,4), (5,6), (1,7) }

1A. Run mystery(G, 3) on the digraph G above. What are the values of (M[1], M[2], ..., M[9]) when the algorithm finishes.

I first wrote: 8, 8, 7, 8, 6, 6, 7, 8, but this is incorrect. This is what the values would have been after mystery(G, 1). The correct answer is: 0,0,7,0,0,6,7,0. (I think!)

1B. Suppose G is ANY digraph without cycles. Describe, in words, what mystery(G, s) returns. (For example "mystery(G,s) counts the number of nodes reachable from vertex s" except that is the wrong answer.)

The largest id of any vertex reachable from s.

1C. Over all input graphs with N vertices and M edges, what is the worst-case running time of mystery(G,v)? (Use big-O notation to give your answer.) Explain, carefully, why.

O(N+M). The running time is the same as DFS. More specifically, the algorithm does work for each vertex proportional to the degree of the vertex, so the total work is proportional to the number of vertices plus the number of edges.

1D. Carefully explain your reasoning that makes you believe your answer to 1B is correct. (If you are not sure that it is correct, be frank about what your doubts are.)

Define MV[v] = maximum id of any vertex reachable from v.

Claim: MV satisfies the following recurrence:

MV[v] = max { v, max { MV[w] : (w,v) ∈ E }}

This is because the set of vertices reachable from v is v, together with the union of the sets of vertices reachable from the out-neighbors of v.

By looking at the algorithm, we can see that it calculates M[v] according to this recurrence. Therefore M[v] as calculated by the algorithm equals MV[v], the maximum id of any vertex reachable from v.


2. Now consider the following algorithm:

 1.  HashTable<int,bool> visited(0);
 2.  HashTable<int,int> S(0);
 3.  
 4. int mystery2(Digraph G, int vid, int vid2) {
 5.     if (! visited[vid])  {
 6.       visited[vid] = 1;
 7.       if (vid == vid2)  S[vid] = 1;  // this line changed
 8.       Array<int> out_nbrs = G.out_nbrs(vid);
 9.       for (int i = 0;   i < out_nbrs.size();  ++i) {
 10.        int P = mystery2(G, out_nbrs[i], vid2); 
 11.        S[vid] += P; // this line changed
 10.     }
 11.  }
 10.  return S[vid];
 11.}

2A. Run mystery2(G, 1, 6) on the example graph from problem 1. What are the values S[1], S[2], ..., S[9] when the algorithm finishes?

I first wrote 2,1,1,0,0,1,0,0, but this is wrong. The correct answer is 3,2,1,0,0,1,0,0 (I think!).

2B. In words, if G is ANY directed acyclic graph, what does mystery2(G, s, t) return?

The number of paths from s to t.


3. ascending subsequences

Given an ordered sequence of numbers, an ascending subsequence is a subsequence that is strictly increasing. For example, within the sequence
(3, 1, 4, 1, 5, 9, 2)
the subsequence (3,4,5,9) (obtained by taking the first, third, fifth, and sixth elements of the original sequence) is the longest asending subsequence.

3A. Find the longest ascending subsequence within this sequence:

S = (9, 13, 11, 8, 18, 18, 0, 3, 1, 0, 8, 6, 14, 8, 16, 7) .

0,1,6,8,16

3B. Suppose A is an array of N integers. For i=0,1,...,N-1, define LAS[i] to be the length of the longest ascending subsequence within (A[0],A[1],A[2],...,A[i]) that ends with A[i] .

For example, for the sequence S, above, we have

LAS[0] = 1, LAS[1] = 2, LAS[2] = 2, LAS[3] = 1, ...
For the sequence S, what are the values of LAS[4], LAS[5], LAS[6], ... , LAS[15] ?

1,3,3,1,2,2,1,3,3,4,4,5,4

3C. Describe a a recurrence relation between LAS[i] and the values (LAS[0], LAS[1], ..., LAS[i-1]) and the values (A[0], A[1], ..., A[i]). (one that holds for any sequence of N integers, where N can be any positive integer). Hint: your rule should be implementable in O(i) time, once the values (LAS[0], LAS[1], ..., LAS[i-1]) have been computed.

Another hint: a longest ascending subsequence ending at A[i], if you remove A[i], gives either the empty sequence, or it gives a longest ascending subsequence ending at some A[j] for j < i and A[j] < A[i].

LAS[i] = max { 1, 1 + max { LAS[j] : 1 ≤ j < i and A[j] < A[i] }

3D. Describe an efficient algorithm for computing the length of the longest ascending subsequence, given a sequence (A[0], A[1], A[2], ..., A[N]). Use pseudo-code to describe your algorithm. What is the running time of your algorithm?

 1.  For i = 1 .. n do
 2.    LAS[i] = max { 1, 1 + max { LAS[j] : 1 ≤ j < i and A[j] < A[i] }  
 3.  return  max { LAS[i] : 1 ≤ i ≤ n } .

The running time is O(n2). Line 2 can be computed in O(n) time.

3E. Prove that your recurrence relation from 3C is correct.

The correctness of the recurrence follows from the following claim:

The longest ascending subsequence ending at (and including) A[i] is either {A[i]} or it is a longest ascending subsequence ending at A[j] (where j < i and A[j] < A[i]), followed by A[i].

This claim may be obvious, but in case it is not we give a line of reasoning that is broken down into even more obvious steps.

First, for any j such that j < i and A[j] < A[i], the longest ascending subsequence ending at A[j], followed by A[i], is an ascending subsequence ending at A[i]. Thus, LAS[i] ≥ 1+LAS[j] for any such j. Thus, LAS[i] ≥ 1+max { LAS[j] : j < i and A[j] < A[i].

Clearly LAS[i] ≥ 1.

Combining the last two paragraphs, we get

LAS[i] ≥ max { 1, 1+max { LAS[j] : j < i and A[j] < A[i] }.

---

To finish we need only convince ourselves that

LAS[i] ≤ max { 1, 1+max { LAS[j] : j < i and A[j] < A[i] }.

Let S be a longest ascending subsequence ending (and including) A[i], so that the length of S is LAS[i].

Let S' be the subsequence S without the final term A[i]. If S' is empty, then LAS[i] = 1.

Otherwise, S' ends in some A[j] with j < i. Since S was an ascending subsequence, it must also be that A[j] < A[i]. Also, it must be that S' is an ascending subsequence. Thus, LAS[j] ≥ length(S') = LAS[i] - 1.

From the previous two paragraphs we can conclude that either LAS[i] = 1, or there exists a j with j < i and A[j] < A[i] such that LAS[i] ≤ LAS[j] + 1. Thus,

LAS[i] ≤ max { 1, 1+max { LAS[j] : j < i and A[j] < A[i] }.

ClassS04CS141 | ClassS04CS141 | recent changes | Preferences
This page is read-only | View other revisions
Last edited May 14, 2004 9:22 am by Neal (diff)
Search: