Monday, July 28, 2014

Maximum sum of non adjacent subsequence sum

Problem

Finding the maximum subsequence sum such that non of the elements in the sequence are adjacent to each other

Approach

One brute force approach is getting all the combinations, and excluding any combination with adjacent elements and finding the maximum from the remaining combinations. Obviously the approach is exponential. Below is the solution to solve the problem using Dynamic Programming.
In-order to solve a problem using dynamic programming there should be a solution which has optimal substructure and overlapping sub problems properties. And the current problem has optimal substructure property.
Say, f( i) is defined as maximum subsequence sum of non adjacent elements for 'i' items, then
then
f( i) =     0 if i = 0
               max (f(i-1), f(i-2) + a[i])

Below is the algorithm for the same (note it can solved without the encapsulating data in 'record' - i just preferred it this way) - which should illustrate the above idea:
Code Snippet
  1. int FindMaxNonAdjuscentSubsequentSum(int[] a)
  2.         {
  3.             a.ThrowIfNull("a");
  4.             if(a.Length == 0)
  5.             {
  6.                 return 0;
  7.             }
  8.             Record r = new Record()
  9.             {
  10.                 max_including_item = a[0],
  11.                 max_excluding_item = 0
  12.             };
  13.             for (int i = 1; i < a.Length; i++)
  14.             {
  15.                 var t = new Record();
  16.                 //there will be only two cases
  17.                 //1. if it includes the current item, max is maximum of non adjuscent sub
  18.                 //sequence sum so far, excluding the last item
  19.                 t.max_including_item = r.max_excluding_item + a[i];
  20.                 //2. if it excludes current item, max is maximum of non adjuscent subsequence sum
  21.                 t.max_excluding_item = r.Max;
  22.                 r = t;
  23.             }
  24.             return r.Max;
  25.         }

Unit Tests

Code Snippet
  1. [TestMethod]
  2.         [TestCategory(Constants.DynamicProgramming)]
  3.         public void MaxNonAdjascentSubsequenceSum()
  4.         {
  5.             int[] a = new int[] { 3, 2, 5, 10, 7};
  6.             Assert.IsTrue(15 == this.FindMaxNonAdjuscentSubsequentSum(a));
  7.             a = new int[] { 3, 2, 5, 10 };
  8.             Assert.IsTrue(13 == this.FindMaxNonAdjuscentSubsequentSum(a));
  9.             a = new int[] { 5, 10, 40, 50, 35 };
  10.             Assert.IsTrue(80 == this.FindMaxNonAdjuscentSubsequentSum(a));
  11.             a = new int[] { 1, -1, 6, -4, 2, 2 };
  12.             Assert.IsTrue(9 == this.FindMaxNonAdjuscentSubsequentSum(a));
  13.             a = new int[] { 1, 6, 10, 14, -5, -1, 2, -1, 3 };
  14.             Assert.IsTrue(25 == this.FindMaxNonAdjuscentSubsequentSum(a));
  15.         }

Helpers

Code Snippet
  1. public static int Max(int a, int b)
  2. {
  3. return (a > b) ? a : b;
  4. }
  5. class Record
  6. {
  7. public int max_including_item = int.MinValue;
  8. public int max_excluding_item = int.MinValue;
  9. public int Max
  10. {
  11. get
  12. {
  13. return Max(max_including_item, max_excluding_item);
  14. }
  15. }
  16. }

No comments:

Post a Comment