CISC4080, Computer Algorithms,
Midterm Lab

     

Home

Schedule

Assignments

Grading

 

Goal

We will study:

  1. Practice brute force way of solving problems
  2. 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:

  • What are the input, output? How do you represent them?
  • What are the key concepts? In this problem, the key concept is subarray, and maximal subarray (the subarray with the largest sum).
  • How to represent the key entity (here subarray) in program? For this problem, we can represent the subarray using the start and ending indices.
  • Is this a maximimization or minimization problem? The current problem is a maximization problem, as we are looking for a subarray that maximize the sum.
    Among all possible subarrays of the given array, which subarray has the largest sum? 
    	
  • How many subarrays are there totally for a given array A[1...n]? How to iterative through all possible subarrays, calculating their sums?

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):

  1. the maximal subarray of array of A[left...mid] (a recursive call)
  2. the maximal subarray of array of A[mid+1...right] (a recursive call)
  3. 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