Вы находитесь на странице: 1из 5

CSCI 235 Section 3/4 - Spring 2015

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)

Solving this is straightforward using backward substitution:


m(n)

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)

Its worth simplifying the above expression at this point.


m(n)

= 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

To reach the base case, n k = 1 k = n 1. Since m(1) = 0, we have:


m(n)

= 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.

2. Let f oo(n) be defined as follows:


int foo(int n, int q)
{
if(n == 0)
return someFunc(q);
int p = someFunc(q);
int x = foo(n-2, p);
int y = foo(n-2, 2*p);
return y;
}
For simplicity, assume that n is always even. This is a recursive function, and the recursion is dependent
only on the value of n. The second parameter is passed to each call, but it doesnt control how the recursion stops, so in the analysis of this recursion, we dont can imagine that p and q are not there at all.
In this example, lets count the number of times the function someFunc(n) is called. Denote this
number by m(n). We observe that this function is called once in each call of foo(), plus the number
of times that its called by recursive calls to foo(). It is important to note that foo() is called twice
each time. There is also a single call to someFunc() in the base case (n = 0). Using these observations,
we arrive at the following:
m(0)

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)

The base case is n = 0, so we set n 2k = 0, which implies k =


m(n)

n
2.

Then plugin the base case value:


n

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)

which proves our claim.


A note about the sum 20 + 21 + 22 + 23 + + 2n1
To find a closed form of this sum, we set s to 20 + 21 + 22 + 23 + + 2n1 , then do a few tricks:
s =

20 + 21 + 22 + 23 + + 2n1

s =

20 + 21 + 22 + 23 + + 2n1 + 2n 2n

s =

20 + 2(20 + 21 + 21 + + 2n2 + 2n1 ) 2n

s =

20 + 2s 2n

s =

1 + 2s 2n

s =

2n 1

And thus we arrive at


s = 2n 1
Now you dont have to memorize how to derive this, but it is useful. As long as you know that the sum is
equal to 2n 1, you can use it in a variety of ways. However, note that this closed for solution applies to the
sum 20 +21 +22 +23 + +2n1 only. The sum would of course change for different starting and ending points.
Work out closed form solutions for the following yourself:
1. 1 + 2 + 4 + 8 + + 2n
2. 2 + 4 + 8 + + 2n1
3. 1 + 2 + 4 + 8 + . . . + N
4. 1 + 2 + 4 + 8 + . . . + N/2
5. 20 + 21 + 22 + 23 + + 2log2 N
You should not have to re-derive these sums. Simply manipulating the n in the original closed form solution
should suffice.

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

Count and prove the number of multiplication operations m(n) in foo(n,...).


Solution: m(n) = 3 2n 2
2. double foo(int n)
{
if(n == 0)
return 1;
double y = 1;
for(int i=0;i<n;i++)
{
for(int j=0;j<n;j++)
{
y *= SOME_NUMBER;
}
}
return y + foo(n-1);
}
Count and prove the number of multiplication operations m(n) in foo(n).
Solution: Recurrence involves n2 , can be solved using sum of squares formula. Dont worry, this wont
come up in the exam.
3. Only for fun:
double foo(int n)
{
if(n == 0)
return 1.5;
double y = 1;
for(int i=0;i<n;i++)
{
y *= foo(n-1);
}
return y;
}
Solution: Come up with only the recurrence relation of m(n), and check with me (you can email me).

Вам также может понравиться