Академический Документы
Профессиональный Документы
Культура Документы
More Recursion
Ali Ahmed
March 21, 2015
Before we dive into examples and techniques, please note that many times it is possible to guess the
closed-form solution instead of working it out using substitution methods. To guess, plugin reasonable values of n into the recurrence relation and compute the answer (recursively of course). If you have understood
recursion, you should be able to tell that you should start with the smallest values of n, and slowly increase
them, thereby reusing the previously computed values. Compute the answer of 3 or 4 different n, and if you
see a pattern, write it in terms of n, then prove it using induction.
In this document, the examples are too difficult to guess easily. We want to focus on formal techniques of
deriving the closed form solutions. However, in real life (and on tests!), if the recurrence somewhat looks
gentle and tractable, always to try guess first. Examples 1 and 3 from Wednesdays class have easy to guess
closed form solutions - try to guess them.
Examples
1. Assume we have this rather nonsensical C++ function:
int p(n)
{
if(n == 1)
return 1;
int v = 1;
for(int i=0; i<n; i++)
v = v * n;
return v + p(n-1);
}
We want to count the number the multiplications in the execution of p(n) for arbitrary n. Let this
count be m(n).
Note that this function has a for loop with a multiplication operation in the loop body. So for a
particular call of p(n), there are n multiplication operations, plus the number of operations performed
by the subsequent calls. The recursive calls are due to a single call to p(n 1). So we can write the
following recurrence relation for m(n):
m(1)
m(n)
= n + m(n 1)
n + m(n 1)
m(n)
n + (n 1) + m(n 2)
m(n)
n + (n 1) + (n 2) + m(n 3)
m(n)
n + (n 1) + (n 2) + (n 3) + m(n 4)
m(n)
n + (n 1) + (n 2) + (n 3) + + (n (k 1)) + m(n k)
(1)
= n + n 1 + n 2 + n 3 + + n (k 1) + m(n k)
Note that you have have k copies of n, and then 1 2 3 (k 1), which is the negative of
the sum from 1 to k 1. Therefore,
m(n)
nk
(k 1)k
+ m(n k)
2
= n(n 1)
(n 1)(n 2)
+0
2
Proof By Induction
Prove base case (i.e., show that recursions base case can be achieved with closed form solution):
m(1)
1(1 1)
(1 1)(1 2)
2
Now, the inductive hypothesis: assume that it is true for n, i.e., m(n) = n(n 1)
(n1)(n2)
2
So now we have to prove that given the previous assumption, it is true for n + 1 as well. For this, the
first step is to write m(n + 1) in terms of m(n) using the recurrence relation, and then (because of the
assumption) plugin the value of m(n) with what we assumed:
m(n + 1)
(n + 1) + m(n)
(n + 1) + n(n 1)
=
=
=
=
(n 1)(n 2)
// change m(n) to closed form
2
2n + 2 + 2n2 2n n2 + 3n 2
2
2n2 + 2n n2 + n
2
2n(n + 1) n(n 1)
2
n(n 1)
n(n + 1)
,
2
which is what we also get via the closed form solution of m(n + 1).
Question: How would this result change if instead of n multiplications in each call, the function
performed a constant C number of multiplications? Write your result in terms of C and n.
m(n)
1 + 2 m(n 2)
Note that we have m(n 2) instead of m(n 1), because thats how the function is defined. If you do
backward substitution for a while, you will arrive at the following relation:
m(n)
1 + 2 + 4 + 8 + 16 + 32 m(n 10)
1 + 2 + 4 + 8 + 16 + + 2k m(n 2k)
n
2.
1 + 2 + 4 + 8 + 16 + + 2 2 1
20 + 2 1 + 2 2 + 2 3 + 2 4 + + 2 2
21+n/2 1
Proof By Induction
Base case: m(0) = 21+0 1 = 2 1 = 1, which is consistent with the recursive relations base case.
Assume m(n) = 21+n/2 1.
Prove for n + 2 (not m + 1, because thats how the recursion is!):
m(n + 2)
1 + 2m(n)
1+n/2
(recurrence relation)
1)
1 + 2(2
1 + 2 21+n/2 2
1 + 22+n/2 2
22+n/2 1
21+(n+2)/2 1
(assumption)
20 + 21 + 22 + 23 + + 2n1
s =
20 + 21 + 22 + 23 + + 2n1 + 2n 2n
s =
s =
20 + 2s 2n
s =
1 + 2s 2n
s =
2n 1
Exercises
1. long foo(int n, ...)
{
if(n == 0)
return NUM1 * NUM2;
long x = foo(n-1, <SOME_ARGUMENTS>);
long y = foo(n-1, <OTHER_ARGUMENTS>);
return x * y * LARGE_NUMBER;
}
4