370 likes | 491 Views
Largest Contiguous Sum. CSC 172 SPRING 2002 LECTURE 2. Today’s Agenda. Largest Sum Problem & Analysis Linked Lists Workshop Sign up. LAB ASSINGMENTS. Labs are due at the beginning of the first lab of the following week Lab hand ins (hardcopy) will be a “report” Hand in to lab TA
E N D
Largest Contiguous Sum CSC 172 SPRING 2002 LECTURE 2
Today’s Agenda • Largest Sum Problem & Analysis • Linked Lists • Workshop Sign up
LAB ASSINGMENTS • Labs are due at the beginning of the first lab of the following week • Lab hand ins (hardcopy) will be a “report” • Hand in to lab TA • Neat, Stapled, Broken into sections • Cover page describing the lab • Listing of required files, properly modified
Example • One dimensional pattern recognition • Input: a vector x of n floating point numbers • Output: the maximum sum found in any contiguous subvector of the input. • X[2..6] or 187 • How would you solve this?
Obvious solution • Check all pairs int sum; int maxsofar = 0; for (int i = 0; i<x.length;i++) for (int j = i; j<x.length;j++){ sum = 0; for (int k = i;k<=j;k++) sum += x[k]; maxsofar = max(sum,maxsofar); }
How long does the obvious solution take? • We could “measure” it – benchmarking • What is a “good size” of input to measure?
How long does the obvious solution take? • We could “analyse” it • Multiply the “cost” (time required) to do something by the number of times you have to do it. • If n is the length of the array • Outer loop runs exactly n times • Inner loop runs at most n times • Inner most loop runs no more than n times • Let’s say the “+=“ and “max” take unit time
How long does the obvious solution take? • We call this an “n3” solution • Can you think of a better (faster) way? • Can you do an analysis that will prove it better? • That is what we do in CSC 172 • For some very common tasks
A better solution • We “notice” that the sum x[i..j] is intimately related to the sum x[i..(j-1)] • Use this fact to prevent taking redundant sums
A better solution • Check all pairs int sum; int maxsofar = 0; for (int i = 0; i<x.length;i++) sum = 0; for (int j = i; j<x.length;j++){ sum += x[k]; // the sum of x[i..j] maxsofar = max(sum,maxsofar); }
How long for the better solution? • Outer loop runs exactly n times • Inner loop runs at most n times • Let’s say the “+=“ and “max” take unit time
How long for the better solution? • Innerloop cost = n * 1 • Outerloop cost = n * (Innerloop cost) Outerloop cost = n * ( n * 1) Outerloop cost = n2 +n
How much better is the “better” algorithm than the “obvious”? • We are comparing an n2 to an n3 algorithm • Does efficiency matter? • If we wait 18 months, the speed of computers will double, right?
Divide & Conquer • To solve a problem of size n, recursively solve two sub-problems of size of size n/2, and combine their solutions to yield a solution to the complete problem.
D&C for LCS x a b ma mb ma , mb or: mc
Recursive D&D LCS public double LCS(double[] x){ return LCS(x,0,x.length-1); }
Recursive D&C LCS (proto structure) public double LCS(double[] x, int lower, int upper){ if (lower>upper) return 0; if (lower == upper) return max(0,x[lower]); middle = (upper + lower) /2; return max(LCS(x,lower,middle), LCS(x,middle+1,upper)); }// still need to do “mc”
How to find mc? • Note that mc consists of two parts • The part starting at the boundary and reaching up • The part ending at the boundary and reaching down • The sum of these is mc mc mclower mcup
Recursive D&D LCS public double LCS(double[] x, int lower, int upper){ if (lower>upper) return 0; if (lower == upper) return max(0,x[lower]); middle = (upper + lower) /2; double umax = findUmax(x,middle+1,upper); double lmax = findLmax(x,lower,middle); return max(LCS(x,lower,middle), LCS(middle+1,upper), lmax + umax); }
findLmax public double findLmax(double[] x, int lower,int middle){ double lmax = 0, sum = 0; for (int j = middle;j>=lower;j--){ sum+=x[j]; lmax = max(lmax,sum); } return lmax; } // Run Time? In terms of middle-lower?
findUmax public double findLmax(double[] x, int middle1,int upper){ double umax = 0, sum = 0; for (int j = middle;j<=upper;j++){ sum+=x[j]; umax = max(lmax,sum); } return umax; } // Run Time? In terms of upper-middle1?
Recursive D&D LCS public double LCS(double[] x, int lower, int upper){ if (lower>upper) return 0; if (lower == upper) return max(0,x[lower]); middle = (upper + lower) /2; double umax = findUmax(x,middle+1,upper); double lmax = findLmax(x,lower,middle); return max(LCS(x,lower,middle), LCS(x,middle+1,upper), lmax + umax); } //Run time of the two calls?
Run Time of D&C LCS • Every call on a range of n takes • n to find umax & lmax • 2 (recursive) calls of size n/2 each Formally TLCS(n) = 2TLCS(n/2)+n As we will see (later in the course) this solves to O(n log n)
LCS Scanning • A scanning algorithm starts at the left end x[0] and proceedes to theright x[n-1] keeping track of the current result • The key to a scanning algorithm is • Given that the problem is solved for the x[0..j-1] range • Do some processing at step j that will extend the partial solution to the x[0..j] range
LCS Scanning • Keep a record of the “best” and the “current” • If the “current” is better than the “best” then replace • How do I extend the maxendinghere? x maxsofar maxendinghere 0 j
Extending maxendinghere • We have up until x[j-1] • Should we include x[j]? • We should if adding x[j] keeps the sum positive • Consider: if the max ending at x[j] is negative then the contribution from x[j] and before cannot be of “benefit” to what comes after • Otherwise, we should reset maxendinghere to zero • The empty vector
LCS Scanning public double LCS(double[] x){ double maxsofar = 0, maxendinghere = 0; for (int j = 0;j<x.length;j++){ maxendinghere = max(maxendinghere+x[j],0); maxsofar = max(maxsofar,maxendinghere); } return maxsofar; } // Run Time?
Design Principles • Save state to avoid recomputation • Preprocess into data structures • Divide and conquer • Scanning algorithms • Cumulatives when dealing with ranges
Open problem • Extend LCS to 2D • Given an nxn array of reals, find the maximum sum contained in any rectangular sub-array • What is the time complexity?
Further reading • Programming Pearls by Jon Bently 2nd ed. 2000