- Published on
Recursive algorithms
- Authors
- Name
- Simon Kurbiel
Introduction
In this section, we will uncover recursive algorithms and study their correctness using induction.
Recursive algorithm
Compute Array Sum
Below is a simple recursive algorithms that sums the elements in an array.
def compute_sum(array:list, length:int)->int:
if(length == 0):
return array[length]
return array[length]+compute_sum(array, length-1)
Recurrence Equation
Let us take a look at some recurrence equations to analyze time complexity
Tower of Hanoi
The tower of hanoi problem has this recurrence equation for
We need to solve this recurrence equation to find directly in terms of n. There are different ways to solve this problem. We will first tackle this problem using substitution. However there is an easier method using the master theorem which we will look at later on.
here is the solution.
after a few substitutions, we can observe the general pattern, and see what is needed to get to the point where the last term becomes
Then we can use the base case of the recurrence equation,
we use the geometric sum and find that
Compute power by repeated multiplications
suppose we want to calculate by repeated multiplications. Here is one way of doing it using a loop, where .
def pow(x:int, n:int)->int:
total = x
for i in range(1,n):
total*=x
return total
However this approach is inefficient because the power goes up by 1 each operation. How can we speed this up?
We can do this by repeated squaring, thus doubling the power by each multiplication. First consider special case when for some integre .
import math
def pow2(x:int, n:int)->int:
k:int= int(math.log(n,2))
total:int = x
print()
for i in range(1,k+1):
total*=total
return total
Now lets generalize this algorithm so it works for any . Lets consider a numerical example such as , where 13 is a decimal number. Since , we first apply repeated suaring to get . Then multiply together to get . The computation can be done as follows:
- Square: =
- Square: =
- Square: =
- Multiply together to get .
Now lets see how we can implement the algorithm recursively.
def power(x:int, n:int)->int:
if n == 1:
return x
total = power(x, int(n/2))
total*=total
if n%2 == 1:
total*=x
return total
Analysis
Let f(n) be the worst-case number of multiplications steps to compute . The number of multiplications made by the recursive call is . The recursive call is then followed by one more multiplication. And in the worst-case, if is odd, the one additional multiplication will be performed. Therefore, the recurrence equation can be written as:
Let us prove by induction that the solution is as follows, where the is in base 2.
base case, , from the recurrence, . the claimed solution is . So the base is correct
induction step: integer may be expressed as follows, for some integer .
This means that . Also,
Thus, . To prove the claimed solution for any , suppose the solution is correct for all smaller values. That is,
In particular, for ,
Then,
This concludes the induction proof
Divide and conquer algorithms
The divide-and-conquer is a recursive strategy to divide problems of give size into smaller subproblems of the same type but different size. Then, supposing that the smaller size subproblems are solved recursively, the strategy is to try to obtain the solution to the original problem. Heres a simple example.
Finding max by divide and conquer
def max_recursive(array:list):
if(len(array) == 1):
return array[0]
bp:int = int(len(array)/2)
T1:int = max_recursive(array[0:bp])
T2:int = max_recursive(array[bp:])
if T1> T2:
return T1
return T2
The algorithm is simple. It divides the array into two halves, finds the maximum of each have, compares them and returns the maximum value of the entire array.
Analysis for special case
suppose
let be the number of comparisons to find the maximum in an array. To simply the analysis, we assume that , for some integer . In this case, the size of each half is exactly , and the number of comparisons to find the max of each half is .
we can easily solve this by substitution.
Analysis and proof for generlal n
The recurrence equation becomes:
it's easy to prove that the solution is still
- base case, , , checks out.
- Now, suppose that , . In particluar, for case where , the hypothesis is that
- Then,