Ryan Harrison My blog, portfolio and technology related ramblings

Maximum Sum Area

As a follow up to my previous post where we found the maximum sum subsequence of a one dimensional array, in this post the idea will be extended to cover 2d arrays or grids of numbers.

Instead of finding the subsequence of the array that contains the maximum sum, now the region of the array with the maximum sum will be found. For example in the image below, the region of the array with the largest sum is found to be enclosed by the points (1,1) and (3,2).

Maximum Sum Area example

Here is the algorithm. Note that this is massively inefficient with an order of O(n^6) - meaning that if we double the input size, the time taken calculate the result will increase by a factor of 64 (2^6).

  
/**  
* Sum an area of a 2d array starting from specified coordinates  
*  
* @param i  
* x1  
* @param j  
* y1  
* @param k  
* x2  
* @param l  
* y2  
* @param arr  
* The 2d array to sum the elements of  
* @return The sum of the array from (i, k) to (j, l)  
*/  
private static int sumArea(int i, int j, int k, int l, int[][] arr) {  
    int sum = 0;  
    for (int m = i; m <= k; m++) { 
        for (int n = j; n <= l; n++) { 
            sum = sum + arr[m][n]
        } 
    } 
    return sum; 
} 

/** Calculate the maximum sum region of a 2d array Note this algorithm is extremely inefficient - O(n^6) 
* @param arr
* The 2d array to find the maximum sum region of 
* @return An array containing { x1, y1, x2, y2, sum } 
*/ 
public static int[]] maxSumArea(int[][] arr) { 
    int tmp; 
    int maxiSoFar = 0;
    int maxjSoFar = 0;
    int maxkSoFar = 0;
    int maxlSoFar = 0;
    int maxSumSoFar = 0;
    for (int i = 0; i < arr.length; i++) {
        for (int j = 0; j < arr[0].length; j++) {
            for (int k = i; k < arr.length; k++) {
                for (int l = j; l < arr[0].length; l++) {
                    tmp = sumArea(i, j, k, l, arr);
                    if (tmp > maxSumSoFar) {  
                        maxiSoFar = i;  
                        maxjSoFar = j;  
                        maxkSoFar = k;  
                        maxlSoFar = l;  
                        maxSumSoFar = tmp;
                    }
                }  
            }  
        }  
    }  
    return new int[] { maxiSoFar, maxjSoFar, maxkSoFar, maxlSoFar, maxSumSoFar };  
}  

Here is also a small tester method displaying how the method can be used with the same 2d as shown in the example above -

  
public static void main(String[] args) {  
    final int[][] testArray = {  
    { 1, 4, -2, -8, 3 },  
    { -5, 7, 12, 2, -4 },  
    { 1, 13, -2, 6, -11 },  
    { 2, -9, 3, -18, 3 },  
    { 5, -7, 2, 1, 5 }  
    };

    int[] result = maxSumArea(testArray);  
    System.out.printf("x1 = %d; y1 = %d; x2 = %d; y2 = %d\n", result[0], result[1], result[3], result[2]);  
    System.out.println("Maximum sum area = " + result[4]);  
    System.out.println();

    for (int i = result[0]; i <= result[2]; i++) { 
        for (int j = result[1]; j <= result[3]; j++) { 
            System.out.print(testArray[i][j] + "\t"); 
        } 
        System.out.println(); 
    } 
} 

Which generates the output -

 
x1 = 1; 
y1 = 1; 
x2 = 3; 
y2 = 2 
Maximum sum area = 38 7 12 2 13 -2 6 
Read More

Domain Change

So I’ve finally managed to change my domain name to ryanharrison.co.uk. It was the original one I wanted, but was unavailable when I created the site so I had to pick an alternative. But recently when I came to renew my alternative domain name, I checked the availability and I quickly snatched it up. Not before however I had already renewed my old domain name for another three years which was a bit of a waste in hindsight.

My hosting company made the change of domain names really quickly and easy. It was literally just a case of changing the domain name in a textfield and hitting ‘confirm’. The migration of this WordPress site to the new domain was a little more work but still was pretty easy. It just involved modifying a couple of the WordPress PHP configuration files along with the database itself to update the home URL.

Currently my hosting plan only includes support for one domain name, so raharrison.co.uk will probably go unused unless I upgrade my plain when I next renew. I could then forward the old domain to this new one, but we’ll see how large the price jump is.

In the meantime I also need to update a load of links in my previous posts which might take a while. So some links might be broken at the moment until I fix them.

Read More

Maximum Sum Subsequence

The maximum sum subsequence of an array is the consecutive group of numbers that have the largest sum.

For example with the array {1, 11, -9, -20, 7, 10, -6, 3, 4, -2}, the maximum sum subsequence is 18 using the elements {7, 10, -6, 3, 4} starting from index 4 and ending at index 8.

Here are a few algorithms implemented in Java of increasing efficiency that can be used to solve this problem.

1. Brute Force -; take each element as a starting point and each element after as an ending point, sum the elements in between and keep track of the largest sum.

Efficiency (Order of Growth) = O(n^3)

 
// Calculate the maximum sum of a subsequence of an array  
// Returns an array containing the start index, end index and maximum sum  
// This algorithm has an order of O(n^3)  
public static int[] maximumSumSubsequence(int[] values) {  
	int max = 0;  
	int start = 0;  
	int finish = 0;

	for(int i = 0; i < values.length; i++) { 
		for(int j = i; j < values.length; j++) { 
			int sum = sumSequence(values, i, j); 
			if(sum > max) {  
				max = sum;
				start = i;  
				finish = j;  
			}  
		}  
	}

	return new int[] { start, finish, max };  
}

// Returns the sum of the elements of an array from start to finish inclusive  
private static int sumSequence(int[] values, int start, int finish) {  
	int sum = 0;  
	for(int i = start; i <= finish; i++) { 
		sum += values[i]; 
	} 
	return sum; 
}

Although this works well, it scales extremely badly with the algorithm taking nearly half a second with only 2000 elements. As the size of the input doubles, the time taken will increase by a factor of 8 - not good.

2. Remember the current sum. Instead of computing the sum of elements i to j on each iteration of the innermost loop, we can instead remember the current sum of the elements. This increases the efficiency by a factor of O(n).

Efficiency (Order of Growth) = O(n^2)

// Calculate the maximum sum of a subsequence of an array 
// Returns an array containing the start index, end index and maximum sum 
// This algorithm has an order of O(n^2) 
public static int[] maximumSumSubsequence(int[] values) { 
	int max = 0; 
	int start = 0; 
	int finish = 0; 
	for(int i = 0; i < values.length; i++) { 
		// now we remember the current sum on each iteration of the inner loop 
		int sum = 0; 
		for(int j = i; j < values.length; j++) { 
			sum += values[j]; 
			if(sum > max) {  
				max = sum;  
				start = i;  
				finish = j;  
			}  
		}  
	}
	return new int[] { start, finish, max };  
}  

This optimisation, although small saves a lot of execution time. Now as the size of the input array doubles, the time taken will increase by a factor of 4. However we can still improve this and gain a linear relationship between size and execution time.

3. Single loop -; now we only traverse the array once. We keep track of the maximal sum subsequence so far and the maximal sum subsequence ending at the current position.

Efficiency (Order of Growth) = O(n)

 
// Calculate the maximum sum of a subsequence of an array  
// Returns an array containing the start index, end index and maximum sum  
// This algorithm has an order of O(n)  
public static int[] maximumSumSubsequence(int[] values) {  
	int max = 0;  
	int start = 0;  
	int finish = 0;

	int endStart = 0;  
	int endMax = 0;

	for(int i = 0; i < values.length; i++) { 
		endMax += values[i]; 
		if(endMax > max) {  
			max = endMax;  
			start = endStart;  
			finish = i;  
		}

		if(endMax < 0) { 
			endMax = 0; 
			endStart = i + 1;
		} 
	} 
	return new int[] { start, finish, max };
}

Now we have the best case scenario for this problem. We cannot get any better as in the worst case scenario each element of the array has to be looked at at least once. With the now linear order of growth as the size of the input doubles, the time taken also doubles.

Read More

Installed Visual Studio 2012

Today I decided to take the step and upgrade from Visual Studio 2012 Professional to Visual Studio 2012 Premium so that I could take advantage of some of the language updates in .Net 4.5 and also be able to produce applications for the Windows Store. It also seemed like a good move as I can now get the software for free with the MSDNAA (Dreamspark Premium) account from my university.

I would have done it sooner but I knew it would probably be a long and laborious process trying to uninstall every element of my previous Visual Studio 2010 to then install the newer versions for 2012. I was not wrong. I really wish Microsoft would provide a good uninstaller for Visual Studio. At the moment the main uninstaller gets rid of just the main application, not any of the other stuff that it installs with it. You therefore have to manually go through your control panel trying to find things that may have been installed from VS 2010 - which takes a long time considering that Windows uninstallers are not the quickest of things at the best of times.

When I was finally able to get rid of just about everything, the installation process for Visual Studio 2012 went through without a hitch (the same for which could not be said for 2010). The installer itself was also very nicely designed and seemed to me at least faster than for VS 2010.

Here are a few screenshots -

Installation

Installed

Start Page

I really like the look and feel of the new styled interface so far. However I may have to try and figure out a way of reverting back to the old non-capitalised versions of the menu items.

Read More

New GitHub Account

Upon my recent post on my transferral from SVN to Git, I’ve now signed myself for a GitHub account.

I’m now in the process of uploading some previous projects up to GitHub for safe keeping which no doubt will prove helpful at some point.

Additionally this will enable me to simply link to a repository on GitHub instead of hosting project zip files here on this blog. This will no doubt make it much easier to give updates on any new changes to the code.

You can find my account at http://github.com/raharrison

Read More