// Stuart Reges handout #12 // 4/13/05 // // This program explores three different solutions to the problem of finding // the maximum sum possible given a sequence of integers. The program // constructs an array of random integers between -500 and +500 and runs // each of the three algorithms, keeping track of how much time they take // to run. import java.util.*; public class MaxSum { public static final boolean DEBUGGING = false; // if true, we see list // contents public static void main(String[] args) { // find out how big of a list to process Scanner console = new Scanner(System.in); System.out.print("How many numbers do you want to use? "); int n = console.nextInt(); // construct the list int[] numbers = new int[n]; for (int i = 0; i < n; i++) numbers[i] = (int)(1001 * Math.random()) - 500; // need some timing variables and print the list if debugging long start; double elapsed; if (DEBUGGING) printRange(numbers, 0, n - 1); // test of algorithm 1 start = System.currentTimeMillis(); findMax1(numbers); elapsed = (System.currentTimeMillis() - start)/1000.0; System.out.println("findMax1 took " + elapsed + " seconds"); System.out.println(); // test of algorithm 2 start = System.currentTimeMillis(); findMax2(numbers); elapsed = (System.currentTimeMillis() - start)/1000.0; System.out.println("findMax2 took " + elapsed + " seconds"); System.out.println(); // test of algorithm 3 start = System.currentTimeMillis(); findMax3(numbers); elapsed = (System.currentTimeMillis() - start)/1000.0; System.out.println("findMax3 took " + elapsed + " seconds"); System.out.println(); } // This method uses the brute force method of finding every possible // starting and stopping index and adding up the values in that range. // It has O(n^3) complexity. Assumes list.size > 0. public static void findMax1(int[] list) { // initalize max sequence to just the first element of the list int max = list[0]; int maxStart = 0; int maxStop = 0; long lineCount = 0; for (int start = 0; start < list.length; start++) for (int stop = start; stop < list.length; stop++) { int sum = 0; for (int k = start; k <= stop; k++) { sum += list[k]; lineCount++; } if (sum > max) { max = sum; maxStart = start; maxStop = stop; } } System.out.println("Max = " + max); System.out.println("Max start = " + maxStart); System.out.println("Max stop = " + maxStop); System.out.println("Line count = " + lineCount); if (DEBUGGING) printRange(list, maxStart, maxStop); } // This method improves on the brute force method by keeping partial sums // instead of recomputing from scratch each time. It has O(n^2) // complexity. Assumes list.size > 0. public static void findMax2(int[] list) { // initalize max sequence to just the first element of the list int max = list[0]; int maxStart = 0; int maxStop = 0; long lineCount = 0; for (int start = 0; start < list.length; start++) { int sum = 0; for (int stop = start; stop < list.length; stop++) { lineCount++; sum += list[stop]; if (sum > max) { max = sum; maxStart = start; maxStop = stop; } } } System.out.println("Max = " + max); System.out.println("Max start = " + maxStart); System.out.println("Max stop = " + maxStop); System.out.println("Line count = " + lineCount); } // This method keeps a running sum, resetting the starting point and // resetting the sum to 0 if the sum ever goes negative. It has O(n) // complexity. Assumes list.size > 0. public static void findMax3(int[] list) { // initalize max sequence to just the first element of the list int max = list[0]; int maxStart = 0; int maxStop = 0; long lineCount = 0; int start = 0; int sum = 0; for (int i = 0; i < list.length; i++) { lineCount++; if (sum < 0) { start = i; sum = 0; } sum += list[i]; if (sum > max) { max = sum; maxStart = start; maxStop = i; } } System.out.println("Max = " + max); System.out.println("Max start = " + maxStart); System.out.println("Max stop = " + maxStop); System.out.println("Line count = " + lineCount); } // pre : 0 <= start <= stop < numbers.length // Prints the specified range of numbers 15 per line public static void printRange(int[] numbers, int start, int stop) { int count = 0; for (int i = start; i <= stop; i++) { System.out.print(numbers[i] + " "); count++; if (count % 15 == 0) System.out.println(); } System.out.println(); System.out.println(); } }
Stuart Reges
Last modified: Tue Jan 31 23:54:34 PST 2006