Search code examples
pythondivide-and-conquer

Divide and Conquer array summation or Loop based array Summation?


I tried to sum an array using this two Algorithms:

  • The Divide and Conquer based
  • The Naive Loop based Algorithm

Here is the code:

# Summation divide and conquer
def summation(array,left,right):
   if left == right:
       return array[left]
   else:
       if left == right-1:
           return array[left] + array[right]
       else:
           mid  = left + (right-left)//2
           left_hand = summation(array,left,mid)
           right_hand = summation(array,mid+1,right)
           return left_hand + right_hand

And..

# Loop summation
def summation_normal(array):
   sums = 0
   for i in range(len(array)):
       sums += array[i]
   return sums

Both of the above algorithms are working correctly and asymptotically both are O(n).

But I am not able to Identify whether which one of them is faster. Please help


Solution

  • The number of additions performed on array values is (almost!) the same in both algorithms, but the recursive one has more overhead, so it will run slightly slower.

    You can visualise the recursive algorithm going through a binary tree, taking the values of two child nodes and summing them into their parent node. So the number of additions (of array values) corresponds to the number of inner nodes of that tree.

    Now look at a short array of 2 elements (with indexes 0 and 1):

           +
          / \
         0   1
    

    The plus represents the only addition that happens in the recursive algorithm. Now visualise that one element is added to the array. This means one of the leaf-nodes becomes a parent of two leaf nodes (one leaf node is added). For example:

           +
          / \
         +   2
        / \
       0   1
    

    So now one more addition needs to be performed: there is one more inner node. You can easily see that adding another array element in this structure increases the number of inner nodes with 1. So there will be one more addition.

    Again, in the tree representation, the leaf nodes represent the array values and the inner nodes represent the intermediate sums that are made.

    The number of leaves in a binary tree is always one more than the number of inner nodes. And so the number of additions involving array values is n-1. This is one less than the iterative solution, because there the first (and extra) addition is 0 + array[0]. You could improve that by starting with array[0] and start your loop at index 1. If you do that, both algorithms will perform n-1 additions involving array values.

    Obviously the recursive algorithm has more "housekeeping" to do: calculating the middle index, using the stack for passing arguments, ...etc, so it will be a bit slower, but not with a different time complexity.