Largest Contiguous Sum
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.
31 -41 59 26 -53 58 97 -93 -23 84
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?
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
Hr 14,000 6.0*105
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
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
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?
Time to solve (Bently)
1.3n3 10n2 47nlog2n 48n
103 1.3 sec 10msec .4msec 0.5 msec
104 22 min 1 sec 6 msec .5 msec
105 15 days 1.7 min 78 msec 5 msec
106 41 years 2.8 hours .94 sec 48 msec
107 41 millennia 1.7 weeks 11 sec .48 sec
Max Problem (Bently)
1.3n3 10n2 47nlog2n 48n