Document Sample

CScD-501, Design and Analysis of Algorithms Assignment 2, Spring 2004 Instructor’s Solution Algorithm 1: Linear search with intelligent up-date. Initialize Max1 and Max2 from x[0] and x[1] — one comparison Traverse the array starting at subscript k = 2 o If x[k] > Max1, we update BOTH Max1 AND Max2 — one comparison Max2 Max1 Max1 x[k] o If x[k] > Max2, just update Max2 — one more comparison Max2 x[k] Best case situation: each time we find a new max — note that only one comparison is performed in that case. Based on the loop structure, it contributes n–2 comparisons, and the initial setting gives one more: n–1 comparisons in all achieved with forward-sorted data. Worst case situation: we never discover a new max (x[0] or x[1] contains the maximal value). Thus we always perform two comparisons. Based on the loop structure, this gives 2(n–2) comparisons, and the initial setting gives one more: 2n–3 comparisons in all achieved with reverse-sorted data. Average case situation: this will be based on how often we find a new max — fairly rare event with random data. Experimental results show this to deviate very little from the worst case. Algorithm 2: Recursive search, suggested by text’s optimal MaxMin algorithm If size of array segment < 4 o Initialize Max1 and Max2 from the first two cells — one comparison o If segment size is 3 ∆ If unused cell is < Max2, take no further action — one comparison ∆ Otherwise if unused cell is < Max1, update just Max2 — one more comparison ∆ Otherwise update both Max1 and Max2 Otherwise recursively get the two largest elements in the left and the right half o If left Max1 > right Max1 — one comparison Max1 left Max1 Max2 larger of left Max2 or right Max1 — one comparison o Otherwise Max1 right Max1 Max2 larger of right Max2 or left Max1 — one comparison Printed 2012-Jul-30 at 08:42 Analysis Basis cases: Size 2: single comparison Size 3: one comparison based on the first two cells one comparison to check for update based on the unused cell IF that is used, perform one more comparison to determine the extent of the update Recursive case: Comparison based on the two recursive calls plus always two comparisons to select the two maximal elements nc(n) = nc(n/2)left + nc(n/2)right + 2 Thus we can build tables deriving from the two base cases. In addition, the size-3 base case supports a best case (third cell is NOT used, for two comparisons — reverse-sorted data) and a worst case (third cell IS used, for three comparisons — forward-sorted data). n nc(n) n nc_b(n) nc_w(n) 2 1 3 2 3 4 4 6 6 8 8 10 12 14 18 16 22 24 30 38 32 46 48 62 78 64 94 96 126 158 Starting from n=2, we find a linear relationship: nc(n) = 3/2 n – 2 Starting from n=3, we find two linear relationships, one for best case, the other for worst case: nc_b(n) = 4/3 n – 2 nc_w(n) = 5/3 n – 2 The proof of these equations from the recurrence and the base cases given is straight-forward. For sizes that are not cleanly either a power of two or three times a power of two, we have a mixing of the base cases. Odd base-case behavior grows in as we progress from 2k up to 1.5 2k (the point at which all base cases involve three), and then diminishes up to 2k+1 — the experimental results show this clearly. The average case, from experimental runs, seems roughly to average together the two behaviors when there is an odd-sized base case, for approximately nc(n) = 3/2 n – 2. There seems, however, to be more contribution from the “worst-case” side, so that the average plot bows upwards between powers of two. You can see this by sighting along the curve from the edge of the page. Printed 2012-Jul-30 at 08:42 Algorithm 1: Linear Search 140 120 Number of comparisons 100 80 60 40 20 0 0 8 16 24 32 40 48 56 64 Array Size F(alg-1) A(Alg-1) R(Alg-1) Printed 2012-Jul-30 at 08:42 Algorithm 2: Recursive Search, based at 2 and 3 140 120 Number of Comparisons 100 80 60 40 20 0 0 8 16 24 32 40 48 56 64 Array Size F(alg-2) A(Alg-2) R(Alg-2) Printed 2012-Jul-30 at 08:42 Optimal Algorithm: Single Elimination Tournament With List Traversal As discussed in Ch. 10 of our text, the optimal solution to this problem uses a single-elimination tournament in which winners retain a linked list of opponents that have lost to them. When there is only one player left, the second-ranked player will necessarily have lost to this player sometime. This particular tournament does not have players in seeded positions, so it is possible that “Max2” lost to “Max1” at the very beginning of the tournament. For a single-elimination tournament, we need to have a power of two for the initial positions. This generates the possibility of a “bye” — player[k] is playing against player[k+1], but if there is no player[k+1], then player[k] advances to the next round of the tournament automatically, even if there is no player[k]. For instance, if we have 2k+1 players, and we use the pairing indicated above (i.e., adjacent players contend with each other), the half of the tournament that consists of player 2k+1 through player 2k+1 will pass player 2k+1 through with a series of “byes” until that player is matched with the winner of the matching player 1 through player 2k in the final match. Analysis is easiest for the situation where the array size is an even power to 2: n = 2k. The tournament player will involve 2k-1 + 2k-2 + . . . + 2 + 1 comparisons: n–1. The list of losers will reflect the number of matches — the binary tree size, which is given by log(n), that is, k. When the array size is not an even power of 2, the tournament comparisons reflect all the matches with two players — the “byes” do not require comparisons. The final traversal of the loser list will vary depending on how many “byes” were encountered. Thus the best case will that in which the data are sorted in a forward direction (so that the largest element is in the last position), since the last element will encounter the largest number of “byes”. The very best case will be that with 2k+1 array elements with the largest at the end. That element will be passed forward by “byes” until the final match, so that its loser list will have only a single entry — the second-largest element in the array. The code, unfortunately, becomes more . . . convoluted to perform the tournament, maintain the loser lists, and then find the runner-up. Also, the code example attached is in Java. Were this implemented in an environment without automatic garbage collection, the algorithm would need to be reworked to eliminate the massive memory leaks that a naïve translation would generate. Side note: what if . . . we decided to find the second-largest by doing a double-elimination tournament. That is, the first time an entry loses, it enters into a second tournament that is played by those who have lost once. The second-largest should then succeed in winning this tournament, so we don’t have to have all those . . . lists! The problem is that the consolation tournament has initial size 2k-1, meaning that it will take 2k-1 – 1 comparisons, so that the two tournaments together put us back at about 3/2 n. Printed 2012-Jul-30 at 08:42 Tournament Implementation 80 70 Number of Comparisons 60 50 40 Note: Fwd sorted data generates 30 numerous "byes" in the 20 tournament 10 0 0 8 16 24 32 40 48 56 64 Array Size T(Fwd) T(AvgRnd) T(Rev) Printed 2012-Jul-30 at 08:42 Finding the Largest Two Entries in an Array Sequential Algorithm — Intelligent Update of Second Largest else // RECURSIVE CASE {//NOTE: Each recursive instance needs local scratch objects MyInt v1a = new MyInt(), static void maxPair( MyInt[] x, MyInt maxValue1, MyInt maxValue2 ) v1b = new MyInt(), { v2a = new MyInt(), int k, n = x.length; v2b = new MyInt(); int mid = (hi + lo) / 2; if ( x[0].compareTo(x[1]) > 0 ) top2( x, lo, mid, v1a, v2a ); { maxValue1.set(x[0]); maxValue2.set(x[1]); } top2( x, mid+1, hi, v1b, v2b ); else // True max in left pair { maxValue1.set(x[1]); maxValue2.set(x[0]); } if ( v1a.compareTo(v1b) > 0 ) for ( k = 2; k < n; k++ ) { { v1.set(v1a); if ( x[k].compareTo(maxValue1) > 0 ) // Possible 2nd max: 1st right or 2nd left { if ( v1b.compareTo(v2a) > 0 ) maxValue2.set(maxValue1); v2.set(v1b); maxValue1.set(x[k]); else } v2.set(v2a); else if ( x[k].compareTo(maxValue2) > 0 ) } maxValue2.set(x[k]); // True max in right pair } else } { v1.set(v1b); // Possible 2nd max: 1st left or 2nd right Recursive Algorithm — Consolidate two pairs of maximal items if ( v1a.compareTo(v2b) > 0 ) v2.set(v1a); /** else * Recursive method to find the top 2 values v2.set(v2b); * } * Base cases: sizes 2 and 3 --- presumably never called with hi==lo } * } * For size 2, simply set in order. Then for size 3, adjust based on the * extra value. * * For size > 3, find the top two values of the left and the right side. * Then select the top two based on those two ORDERED pairs. */ static void top2 ( MyInt[] x, int lo, int hi, MyInt v1, MyInt v2 ) { if ( (hi-lo) < 3 ) // BASE CASE {//Either size two or size three if ( x[lo].compareTo(x[lo+1]) < 0 ) { v1.set(x[lo+1]); v2.set(x[lo]); } else { v1.set(x[lo]); v2.set(x[lo+1]); } if ( (hi-lo) == 2 ) // That is, size of 3 if ( x[hi].compareTo(v2) > 0 ) if ( x[hi].compareTo(v1) > 0 ) { v2.set(v1); v1.set(x[hi]); } else v2.set(x[hi]); // else NOTHING // If third value LESS than second, there is NO correction. } Printed 2012-Jul-30 at 08:42 Optimal Algorithm: Single-Elimination Tournament With Addendum size >>= 1; // Right shift by one <==> divide by two } mx1.set(player[0].get()); /** current = player[0].next; * Single-elimination tournament to find largest AND SECOND-LARGEST. t1 = current.get(); * current = current.next; * For each win, maintain a stack-discipline list of the losing players. while ( current != null ) * When there is only one winner left, its loser list will necessarily { * contain the second-largest. Traverse that list to find the second t2 = current.get(); * largest. if ( t2.compareTo(t1) > 0 ) * t1 = t2; * The tournament necessarily involves a power-of-two number of players. current = current.next; * The initial one (or more) rounds will involve some "byes" --- if there } * is no player[k+1], then player[k] advances to the next round. mx2.set(t1); */ } static void tournament ( MyInt[] x, MyInt mx1, MyInt mx2 ) {//Header cell contains this object from x[], and the start of the // linked list of objects that have LOST to this object. Mutable Integer Class MyInt MyIntList[] player; MyIntList current; // Used in the traversal to find mx2 class MyInt implements Comparable MyInt t1, // Object pulled from a player { static int nCmp = 0; t2; // Ditto int value; int size = 1, // Physical size of player[] j, k, // subscripts and loop variables MyInt() n = x.length; { set(0); } // Find the power of two >= n MyInt (int value) while ( size < n ) { set(value); } size += size; void set (int value) player = new MyIntList[size]; // Initialized with null references { this.value = value; } for ( j = 0; j < n; j++ ) void set (MyInt item) player[j] = new MyIntList(x[j], null); { this.value = item.value; } while ( size > 1 ) int get () { for ( j = k = 0; k < size; j++, k += 2 ) { return value; } { if ( player[k+1] == null ) { player[j] = player[k]; public int compareTo(Object r) if ( DEBUG ) { MyInt right = (MyInt) r; System.out.println ("Bye for position " + k); nCmp++; } return this.value - right.value; else } { t1 = player[k].get(); // Comparison NOT included in the count t2 = player[k+1].get(); public int check(MyInt right) if ( t1.compareTo(t2) > 0 ) { return this.value - right.value; } { player[k].next = new MyIntList ( t2, player[k].next ); player[j] = player[k]; public String toString() if (DEBUG) { return Integer.toString(value); } System.out.println ("Winner in position " + k ); } static public int nCompares() else { int rtn = nCmp; { player[k+1].next = new MyIntList ( t1, player[k+1].next ); nCmp = 0; player[j] = player[k+1]; return rtn; if (DEBUG) } System.out.println ("Winner in position " + (k+1) ); } } } } Printed 2012-Jul-30 at 08:42

DOCUMENT INFO

Shared By:

Categories:

Tags:

Stats:

views: | 2 |

posted: | 7/30/2012 |

language: | |

pages: | 8 |

OTHER DOCS BY dandanhuanghuang

Docstoc is the premier online destination to start and grow small businesses. It hosts the best quality and widest selection of professional documents (over 20 million) and resources including expert videos, articles and productivity tools to make every small business better.

Search or Browse for any specific document or resource you need for your business. Or explore our curated resources for Starting a Business, Growing a Business or for Professional Development.

Feel free to Contact Us with any questions you might have.