package object_out;
import java.util.concurrent.ForkJoinPool;
import java.util.concurrent.RecursiveAction;
public class MaxSumTest {
static private int seqStart = 0;
static private int seqEnd = -1;
/**
* Cubic maximum contiguous subsequence sum algorithm.
* seqStart and seqEnd represent the actual best sequence.
*/
public static int maxSubSum1( int [ ] a )
{
int maxSum = 0;
for( int i = 0; i < a.length; i++ )
for( int j = i; j < a.length; j++ )
{
int thisSum = 0;
for( int k = i; k <= j; k++ )
thisSum += a[ k ];
if( thisSum > maxSum )
{
maxSum = thisSum;
seqStart = i;
seqEnd = j;
}
}
return maxSum;
}
/**
* Recursive maximum contiguous subsequence sum algorithm.
* Finds maximum sum in subarray spanning a[left..right].
* Does not attempt to maintain actual best sequence.
*/
private static int maxSumRec( int [ ] a, int left, int right )
{
int processorCount = Runtime.getRuntime().availableProcessors();
ForkJoinPool pool = new ForkJoinPool(processorCount);
MaxSumRecImpl aMaxSumRecImpl = new MaxSumRecImpl(a, left, right);
pool.invoke(aMaxSumRecImpl);
return aMaxSumRecImpl.result;
}
private static class MaxSumRecImpl extends RecursiveAction {
private int[] a;
private int left;
private int right;
private int result;
private MaxSumRecImpl(int[] a, int left, int right) {
this.a = a;
this.left = left;
this.right = right;
}
protected void compute() {
int maxLeftBorderSum = 0, maxRightBorderSum = 0;
int leftBorderSum = 0, rightBorderSum = 0;
int center = (left + right) / 2;
if ((right - left < 4)) {
result = maxSumRec(a, left, right);
return;
}
MaxSumRecImpl task1 = new MaxSumRecImpl(a, left, center);
MaxSumRecImpl task2 = new MaxSumRecImpl(a, center + 1, right);
invokeAll(task1, task2);
int maxLeftSum = task1.result;
int maxRightSum = task2.result;
for (int i = center; i >= left; i--) {
leftBorderSum += a[i];
if (leftBorderSum > maxLeftBorderSum)
maxLeftBorderSum = leftBorderSum;
}
for (int i = center + 1; i <= right; i++) {
rightBorderSum += a[i];
if (rightBorderSum > maxRightBorderSum)
maxRightBorderSum = rightBorderSum;
}
result = max3(maxLeftSum, maxRightSum, maxLeftBorderSum + maxRightBorderSum);
}
/**
* Recursive maximum contiguous subsequence sum algorithm. Finds maximum sum in subarray spanning a[left..right]. Does not attempt to maintain actual best sequence.
*/
private static int maxSumRec(int[] a, int left, int right) {
int maxLeftBorderSum = 0, maxRightBorderSum = 0;
int leftBorderSum = 0, rightBorderSum = 0;
int center = (left + right) / 2;
if (left == right)
return a[left] > 0 ? a[left] : 0;
int maxLeftSum = maxSumRec(a, left, center);
int maxRightSum = maxSumRec(a, center + 1, right);
for (int i = center; i >= left; i--) {
leftBorderSum += a[i];
if (leftBorderSum > maxLeftBorderSum)
maxLeftBorderSum = leftBorderSum;
}
for (int i = center + 1; i <= right; i++) {
rightBorderSum += a[i];
if (rightBorderSum > maxRightBorderSum)
maxRightBorderSum = rightBorderSum;
}
return max3(maxLeftSum, maxRightSum, maxLeftBorderSum + maxRightBorderSum);
}
}
/**
* Return maximum of three integers.
*/
private static int max3( int a, int b, int c )
{
return a > b ? a > c ? a : c : b > c ? b : c;
}
/**
* Driver for divide-and-conquer maximum contiguous
* subsequence sum algorithm.
*/
public static int maxSubSum4( int [ ] a )
{
return a.length > 0 ? maxSumRec( a, 0, a.length - 1 ) : 0;
}
/**
* Simple test program.
*/
public static void main( String [ ] args )
{
int a[ ] = { 4, -3, 5, -2, -1, 2, 6, -2 };
int maxSum;
maxSum = maxSubSum1( a );
System.out.println( "Max sum is " + maxSum + "; it goes"
+ " from " + seqStart + " to " + seqEnd );
maxSum = maxSubSum4( a );
System.out.println( "Max sum is " + maxSum );
}
}