Beefy Boxes and Bandwidth Generously Provided by pair Networks
Perl Monk, Perl Meditation
 
PerlMonks  

Re: Largest Sum of Consecutive Integers

by blokhead (Monsignor)
on Aug 30, 2006 at 18:53 UTC ( #570453=note: print w/replies, xml ) Need Help??


in reply to Largest Sum of Consecutive Integers

Here's a linear-time algorithm that uses a much different approach than what tye has outlined.. It's probably needlessly dense, but I'm sorry, it came out of my brain in such a form.

If you want to find the best interval within array[i..j], then there are 3 possibilities.

  • The best interval is completely contained within the left half of array[i..j]
  • The best interval is completely contained within the right half of array[i..j].
  • The best interval includes the midpoint of i..j (so it is made up of the best interval in the left half that includes the midpoint, and the best interval in the right half that includes the midpoint).
I'll define a couple of thingies here: OK, so I like to write out dynamic programming algorithms in a logic programming paradigm:
  • best(i,j) is the score of the best interval within array[i..j]
  • lbest(i,j) is the score of the best interval within array[i..j] that includes the left endpoint (i)
  • rbest(i,j) is the score of the best interval within array[i..j] that includes the right endpoint (j)
  • total(i,j) is the sum of the elements in array[i..j].
Here are the rules for the dynamic programming:
lbest(i,i) = rbest(i,i) = best(i,i) = max{ 0, array[i] } best(i,j) = max{ rbest(i,k) + lbest(k+1,j), best(i,k), best(k+1,j) }, where k = int((j+i)/2) lbest(i,j) = max{ total(i,k) + lbest(k+1,j), lbest(i,k) }, where k = int((j+i)/2) rbest(i,j) = max{ rbest(i,k) + total(k+1,j), rbest(k+1,j) }, where k = int((j+i)/2)
We can compute total(i,j) without much overhead by keeping track of an accumulation array (sums of the form array[0..j]). This takes O(n) precomputation for the accumulation sums, and we can compute total(i,j) = sum(array[0..j]) - sum(array[0..i-1]) in constant time.

To compute each lbest(i,j), we split the interval into two intervals of half the size and recurse (with constant computation at this level). So to precompute all the lbest() and rbest() values that we need takes linear time total. Then with all of the lbest() and rbest() precomputed, to compute best(i,j) also just takes two recursive calls for intervals half the size. So the whole algorithm is linear.

OK, so this is probably a lot more machinery than tye suggests, but it gets the job done. I was formulating this before I saw his reply anyway. I wrote some example code for this, but I doubt anyone cares..

There's also the usual pain associated with modifying an algorithm that computes score of the best interval (which this does) to make it return the actual interval itself. ;)

blokhead

Log In?
Username:
Password:

What's my password?
Create A New User
Node Status?
node history
Node Type: note [id://570453]
help
Chatterbox?
[marto]: good morning all
[karlgoethebier]: hi marto
[karlgoethebier]: hi all

How do I use this? | Other CB clients
Other Users?
Others scrutinizing the Monastery: (5)
As of 2017-12-13 12:24 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?
    What programming language do you hate the most?




















    Results (362 votes). Check out past polls.

    Notices?