|
Goal
We will study:
- Practice brute force way of solving problems
- Use divide and conquer method to solve problems
Maximal subarray problem
- Input: an integer array $A[left...right]$ where each element is a positive or negative integer,
- Functionality: find out the subarray of $A$ that has the largest sum among all subarrays of A.
- Output: return the sum and the indices i and j, such that subarray A[i...j] has the largest sum.
To summarize, the functions you are implementing have the following header comment
//return i, j, and sum of A[i...j]
// left<=i<=j<=right
//Example: A[0...8]={1,-30, 20, 20, -3, -2, 18, -30, 5}
//Solution: i=2,j=6, sum=53 (20+20-3-2-18)
// i.e., the maximal subarray is A[2...6]={20,20,-3,-2,18}.
// No other subarray has a larger sum.
void (i,j,sum) max_subarray (int A[], int left, int right,
int & i, int & j, int &s; sum)
Brute force solution
When facing a new problem, always analyze the problem first, by asking the following questions:
After the above analysis, hopefully you have found a solution to the problem. Implement the algorithm, analyze its running time(which is at least n^2 or even n^3), and test it.
Divide and Conquer approach
Apply Divide and Conquer paradigm to solve the problem using the following observation.
Note: remember to include base case in your pseudocode.
The maximal subarray of array A[left...right] is one of the following (where mid=(left+right)/2):
- the maximal subarray of array of A[left...mid] (a recursive call)
- the maximal subarray of array of A[mid+1...right] (a recursive call)
- the maximal subarray that spans both half (i.e, the subarray includes A[mid]) i.e., i<=mid, j>=mid that gives largest sum among all such subarrays. (Hint: this can be done in linear time.)
//pseudocode for this step:
max_sum=A[mid] //the best max_sum so far
max_left=mid; //the left index so far
sum = A[mid];
for (int i=mid-1; i>=left;i--)
// update sum
//is sum larger than max_sum?
// if so, update max_sum and max_left
//similarly find how far to extend to right, to maximize sum
//....
This means you can need to compare which of the above three subarrays yields the largest sum. To find the maximal
subarray of the left-half and right-half (1 and 2 in above list), we only need to call the function recursively.
Implement and test the divide-and-conquer method solution, analyze its running time (in comment), and test it.
Testcase
Please test your two algorithms using a variety of test cases, varying
- the size of input array, varying it from 1, 3, 5, 10, 100, 200.
- the input: all integers are positive, all are negative, and a mix of positive and negative
- the resulting output: see if your algorithms work correctly for the case where the maximal subarray is of size 1, e.g.,
-2 -3 100 -10 9
and other cases that you can think of.
Submission
Please submit each source files, class specficiation file (header file) and implemenetation file (.cpp file), and driver program using the script given. For example,
submit4080 MIDTERM maxsubarray.cpp
|