简体   繁体   中英

Understanding/implementing this enumeration solution for maximum subarray

[This is homework. I'm not asking for code-code, but I might need pseudocode to really grasp this.]

For my algorithms class, we're working on the maximum subarray problem. I've already implemented Kadane's linear solution, as well as the simple enumeration below:

def better_enumeration(Array):
    max_subset_sum = current_sum = 0
    start_subset_index = stop_subset_index =  0

    for i in range(0, len(Array)+1):
        for j in range(i, len(Array)+1):
            current_sum = sum(Array[i:j])

            if current_sum > max_subset_sum:
                max_subset_sum = current_sum
                start_subset_index = i
                stop_subset_index = j
    return (Array[start_subset_index:stop_subset_index], max_subset_sum)

Here are the specifications my professor has supplied:

Algorithm 1: Enumeration. Loop over each pair of indices i, j and compute the sum ∑𝑗𝑘=𝑖 𝐴[𝑘]. Keep the best sum you have found so far.

Algorithm 2: Better Enumeration. Notice that in the previous algorithm the same sum is computed many times. In particular, notice that ∑𝑗 𝑘=𝑖 𝐴[𝑘] can be computed from ∑𝑗−1 𝑘=𝑖 𝐴[𝑘] in O(1) time, rather than starting from scratch. Write a new version of the first algorithm that takes advantage of this observation.

At this point, I understand that once I have the sum of i:j, I can calculate i:j+1 much faster using the current_sum. The sticking points for me, I believe are:

  • I'm not sure at which points I should start calculating current_sum -that is, i:j- and when I should be relying on current_sum to calculate i:j+1.
  • How do I only calculate i:j sometimes, leaving i:j+1 to calculate most values?
  • How do I prevent i:j+1 from overflowing a list of numbers?

UPDATE:

def better_enumeration(Array):
max_subset_sum = current_sum = 0
start_subset_index = stop_subset_index =  0

for i in range(0, len(Array)+1):
    current_sum = 0

    for j in range(i, len(Array)+1):
        current_sum += Array[j]

        if current_sum > max_subset_sum:
            max_subset_sum = current_sum
            start_subset_index = i
            stop_subset_index = j

return (Array[start_subset_index:stop_subset_index], max_subset_sum)

Now I just need to figure out how not to overflow the final iteration of j.

Okay, so we know that we can create a summation through the entire list. Summations have a base case though, this one is 0.

for i in range(0, len(Array)+1):
  current_sum = 0

So 0 goes in the outer loop.

for j in range(i, len(Array)+1):
  current_sum += Array[j]

The next thing you need to know is that the Python range function loops range(x, y-1) . We're overflowing the list here. If we don't overflow this list, then we still get an accurate summation, but we lose the last integer in the maximum subset.

  if current_sum > max_subset_sum:
    max_subset_sum = current_sum
    start_subset_index = i
    stop_subset_index = j

Once we understand how range works, a simple print loop through j, shows that we actually do encounter the full subset during the enumeration:

print 'Loop ' + str(j) + ': ' + str(Array[i:j])

Thus, our final issue is that stop_subset_index should equal j+1 .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM