import java.util.Random; import java.util.Scanner; public class MaxSum { public static void main(String[] args) { Scanner console = new Scanner(System.in); System.out.print("Input size (n): "); int n = console.nextInt(); System.out.print("Algorithm: "); int algorithm = console.nextInt(); // run three trial runs to avoid Java optimizations findMax(algorithm, new int[n]); findMax(algorithm, new int[2 * n]); findMax(algorithm, new int[3 * n]); // run the three timed tests double time1 = timingTest(algorithm, n); double time2 = timingTest(algorithm, 2 * n); double time3 = timingTest(algorithm, 3 * n); System.out.println("Double/single ratio = " + time2 / time1); System.out.println("Triple/single ratio = " + time3 / time1); } // Calculates and returns the maximum subsequence sum // in a given array. Triply nested loop makes it O(n^3) // Pre: a contains at least one positive value. // elmts time approximation // n n ^ 3 // 2 * n (2 * n) ^ 3 = n ^ 3 * 8 // 3 * n (3 * n) ^ 3 = n ^ 3 * 27 public static int maxSum1(int[] a) { int max = 0; for (int start = 0; start < a.length; start++) { for (int stop = start; stop < a.length; stop++) { int sum = 0; // elements from a[start] to a[stop] for (int i = start; i <= stop; i++) { sum += a[i]; } if (sum > max) { max = sum; } } } return max; } // Calculates and returns the maximum subsequence sum // in a given array. Doubly nested loop makes it O(n^2) // Pre: a contains at least one positive value. // elemts time approximation // n n^2 // n * 2 (n * 2) ^2 = n^2 * 4 // n * 3 (n * 3) ^ 2 = n^2 * 9 public static int maxSum2(int[] a) { int max = 0; for (int start = 0; start < a.length; start++) { int sum = 0; // elements from a[start] to a[stop] for (int stop = start; stop < a.length; stop++) { sum += a[stop]; if (sum > max) { max = sum; } } } return max; } // Calculates and returns the maximum subsequence sum // in a given array. Single loop makes it O(n). // Pre: a.length > 0, a contains at least one positive value. // elmts time approximation // n n // 2 * n 2 * n // 3 * n 3 * n public static int maxSum3(int[] a) { int max = a[0]; int sum = 0; for (int i = 0; i < a.length; i++) { // Claim 2: if sum becomes negative, max range cannot start // with any previous values if (sum < 0) { sum = 0; } sum += a[i]; if (sum > max) { max = sum; } } return max; } // Uses specified algorithm to compute max subsequence sum on randomly // generated array of given size. Prints time elapsed. // Pre: size > 0 and 1 <= algorithm <= 3 public static double timingTest(int algorithm, int size) { int[] values = new int[size]; Random rand = new Random(); for (int i = 0; i < values.length; i++) { values[i] = rand.nextInt(1001) - 500; // positive and negative } // get start/stop system times to find out how fast the code ran long startTime = System.currentTimeMillis(); int sum = findMax(algorithm, values); double elapsed = (System.currentTimeMillis() - startTime) / 1000.0; // report and return results System.out.println("\tfor n = " + size + ", time = " + elapsed); return elapsed; } // Pre: 1 <= algorithm <= 3, throws IllegalArgumentException otherwise. public static int findMax(int algorithm, int[] values) { if (algorithm == 1) { return maxSum1(values); } else if (algorithm == 2) { return maxSum2(values); } else if (algorithm == 3) { return maxSum3(values); } else { throw new IllegalArgumentException( "Algorithm number must be between 1 and 3"); } } }