import java.util.Random;
/**
*Maximum continguous subsequence sum algorithm
*连续子序列最大和问题
*/
public class MaxSubSequenceSum
{
static int seqStart = 0;
static int seqEnd = -1;
private static Random rand = new Random( );
/**
*1.Cubic maximum contiguous subsequence sum algorithm.
*seqStart and seqEnd respresent 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 temp = 0;
for(int k = i; k <= j; k++)
temp += a[k];
if(temp > maxSum)
{
maxSum = temp;
seqStart = i;
seqEnd = j;
}
}
return maxSum;
}
/**
*2.Square maximum contiguous subsequence sum algorithm.
*seqStart and seqEnd represent the actual best sequence
*/
public static int maxSubSum2(int[] a)
{
int maxSum = 0;
for(int i = 0; i < a.length; i++)
{
int temp = 0;
for(int j = i; j < a.length; j++)
{
temp += a[j];
if(temp > maxSum)
{
maxSum = temp;
seqStart = i;
seqEnd = j;
}
}
}
return maxSum;
}
/**
*3.Linear-time maximum contiguous subsequence sum algorithm.
*seqStart and seqEnd represent the actual best sequence
*/
public static int maxSubSum3(int[] a)
{
int maxSum = 0;
int temp = 0;
for(int i = 0, j = 0; j < a.length; j++)
{
temp += a[j];
if(temp > maxSum)
{
maxSum = temp;
seqStart = i;
seqEnd = j;
}
else if(temp < 0)
{
i = j+1;
temp = 0;
}
}
return maxSum;
}
/**
*4.Use divide-and-conquer method maximum contiguous
*subsequence sum algorithm.
*/
public static int maxSubSumRec(int[] a, int left, int right)
{
int maxLeftBorderSum = 0;
int maxRightBorderSum = 0;
int leftBorderSum = 0;
int rightBorderSum = 0;
int center = (left+right)/2;
if(left == right) //only have a number
return a[left] > 0 ? a[left] : 0;
int maxLeftSum = maxSubSumRec(a, left, center);
int maxRightSum = maxSubSumRec(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 ThreeOfMax(maxLeftSum,maxRightSum,
(maxLeftBorderSum+maxRightBorderSum));
}
private static int ThreeOfMax(int a, int b, int c)
{
return a>b ? a>c ? a : c : b>c ? b : c;
}
public static int maxSubSum4(int[] a)
{
return a.length > 0 ? maxSubSumRec(a, 0, a.length-1) : 0;
}
public static void getTimingInfo(int n, int algorithm)
{
int[] test = new int[n];
long startTime = System.currentTimeMillis();
long totalTime = 0;
int i;
for(i = 0; totalTime < 4000; i++)
{
for(int j = 0; j < test.length; j++)
test[j] = rand.nextInt(100) - 50;
switch(algorithm)
{
case 1:
maxSubSum1(test);
break;
case 2:
maxSubSum2(test);
break;
case 3:
maxSubSum3(test);
break;
case 4:
maxSubSum4(test);
break;
}
totalTime = System.currentTimeMillis() - startTime;
}
System.out.println("Algorithm-->" + algorithm
+ "\tN= " + test.length + "\t"
+ "\tTime= " + (totalTime*1000/i) + " ms");
}
/**Simple test programe*/
public static void main(String[] args)
{
int a[] = {4,-3,5,-2,-1,2,6,-1};
int maxSum;
maxSum = maxSubSum1(a);
print(maxSum);
maxSum = maxSubSum2(a);
print(maxSum);
maxSum = maxSubSum3(a);
print(maxSum);
maxSum = maxSubSum4( a );
System.out.println( "Max sum is " + maxSum );
for(int n = 10; n <=10000000; n*=10)
for(int algorithm = 4; algorithm >= 1; algorithm--)
{
if(algorithm == 1 && n > 50000)
continue;
getTimingInfo(n, algorithm);
}
}
private static void print(int maxSum)
{
System.out.println( "Max sum is " + maxSum + "; it goes"
+ " from " + seqStart + " to " + seqEnd );
}
}
Answer:
Algorithm-->4 N= 10 Time= 1 ms
Algorithm-->3 N= 10 Time= 0 ms
Algorithm-->2 N= 10 Time= 1 ms
Algorithm-->1 N= 10 Time= 2 ms
Algorithm-->4 N= 100 Time= 20 ms
Algorithm-->3 N= 100 Time= 8 ms
Algorithm-->2 N= 100 Time= 31 ms
Algorithm-->1 N= 100 Time= 709 ms
Algorithm-->4 N= 1000 Time= 219 ms
Algorithm-->3 N= 1000 Time= 81 ms
Algorithm-->2 N= 1000 Time= 2214 ms
Algorithm-->1 N= 1000 Time= 600428 ms
Algorithm-->4 N= 10000 Time= 2368 ms
Algorithm-->3 N= 10000 Time= 814 ms
Algorithm-->2 N= 10000 Time= 222222 ms
/**
*Maximum continguous subsequence sum algorithm
*连续子序列最大和问题
*/
public class MaxSubSequenceSum
{
static int seqStart = 0;
static int seqEnd = -1;
private static Random rand = new Random( );
/**
*1.Cubic maximum contiguous subsequence sum algorithm.
*seqStart and seqEnd respresent 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 temp = 0;
for(int k = i; k <= j; k++)
temp += a[k];
if(temp > maxSum)
{
maxSum = temp;
seqStart = i;
seqEnd = j;
}
}
return maxSum;
}
/**
*2.Square maximum contiguous subsequence sum algorithm.
*seqStart and seqEnd represent the actual best sequence
*/
public static int maxSubSum2(int[] a)
{
int maxSum = 0;
for(int i = 0; i < a.length; i++)
{
int temp = 0;
for(int j = i; j < a.length; j++)
{
temp += a[j];
if(temp > maxSum)
{
maxSum = temp;
seqStart = i;
seqEnd = j;
}
}
}
return maxSum;
}
/**
*3.Linear-time maximum contiguous subsequence sum algorithm.
*seqStart and seqEnd represent the actual best sequence
*/
public static int maxSubSum3(int[] a)
{
int maxSum = 0;
int temp = 0;
for(int i = 0, j = 0; j < a.length; j++)
{
temp += a[j];
if(temp > maxSum)
{
maxSum = temp;
seqStart = i;
seqEnd = j;
}
else if(temp < 0)
{
i = j+1;
temp = 0;
}
}
return maxSum;
}
/**
*4.Use divide-and-conquer method maximum contiguous
*subsequence sum algorithm.
*/
public static int maxSubSumRec(int[] a, int left, int right)
{
int maxLeftBorderSum = 0;
int maxRightBorderSum = 0;
int leftBorderSum = 0;
int rightBorderSum = 0;
int center = (left+right)/2;
if(left == right) //only have a number
return a[left] > 0 ? a[left] : 0;
int maxLeftSum = maxSubSumRec(a, left, center);
int maxRightSum = maxSubSumRec(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 ThreeOfMax(maxLeftSum,maxRightSum,
(maxLeftBorderSum+maxRightBorderSum));
}
private static int ThreeOfMax(int a, int b, int c)
{
return a>b ? a>c ? a : c : b>c ? b : c;
}
public static int maxSubSum4(int[] a)
{
return a.length > 0 ? maxSubSumRec(a, 0, a.length-1) : 0;
}
public static void getTimingInfo(int n, int algorithm)
{
int[] test = new int[n];
long startTime = System.currentTimeMillis();
long totalTime = 0;
int i;
for(i = 0; totalTime < 4000; i++)
{
for(int j = 0; j < test.length; j++)
test[j] = rand.nextInt(100) - 50;
switch(algorithm)
{
case 1:
maxSubSum1(test);
break;
case 2:
maxSubSum2(test);
break;
case 3:
maxSubSum3(test);
break;
case 4:
maxSubSum4(test);
break;
}
totalTime = System.currentTimeMillis() - startTime;
}
System.out.println("Algorithm-->" + algorithm
+ "\tN= " + test.length + "\t"
+ "\tTime= " + (totalTime*1000/i) + " ms");
}
/**Simple test programe*/
public static void main(String[] args)
{
int a[] = {4,-3,5,-2,-1,2,6,-1};
int maxSum;
maxSum = maxSubSum1(a);
print(maxSum);
maxSum = maxSubSum2(a);
print(maxSum);
maxSum = maxSubSum3(a);
print(maxSum);
maxSum = maxSubSum4( a );
System.out.println( "Max sum is " + maxSum );
for(int n = 10; n <=10000000; n*=10)
for(int algorithm = 4; algorithm >= 1; algorithm--)
{
if(algorithm == 1 && n > 50000)
continue;
getTimingInfo(n, algorithm);
}
}
private static void print(int maxSum)
{
System.out.println( "Max sum is " + maxSum + "; it goes"
+ " from " + seqStart + " to " + seqEnd );
}
}
Answer:
Algorithm-->4 N= 10 Time= 1 ms
Algorithm-->3 N= 10 Time= 0 ms
Algorithm-->2 N= 10 Time= 1 ms
Algorithm-->1 N= 10 Time= 2 ms
Algorithm-->4 N= 100 Time= 20 ms
Algorithm-->3 N= 100 Time= 8 ms
Algorithm-->2 N= 100 Time= 31 ms
Algorithm-->1 N= 100 Time= 709 ms
Algorithm-->4 N= 1000 Time= 219 ms
Algorithm-->3 N= 1000 Time= 81 ms
Algorithm-->2 N= 1000 Time= 2214 ms
Algorithm-->1 N= 1000 Time= 600428 ms
Algorithm-->4 N= 10000 Time= 2368 ms
Algorithm-->3 N= 10000 Time= 814 ms
Algorithm-->2 N= 10000 Time= 222222 ms