Solving recurrence relation effiency class? - performance

I am calculating the effiency class of this
R(n) = 2R(n−1)+2.
with the base case of R(1) = 1
using backwards substitution.
My equations came out to
4R(n-2) + 6
8R(n-3) + 14
16R(n-4) +30
I don't see how i can get an equation from this... Is it incorrect?

Not a complete answer because this looks like homework, but let’s say that each step of the relation doubled in complexity, so f(1) = 1, f(2) = 2, f(3) = 4, f(4) = 8, and so on. What kind of growth is this? What is the equation for f(n)?
Now, suppose it was g(n) = 2g(n-1) + 1, with g(1) = 1. We see that the sequence is 1, 3, 7, 15, etc, which looks a lot like 2^n-1, so let’s check our intuition. For g(n) = a2^n + b, we get 2g(n-1) + 1 = 2[a2^(n-1) + b] + 1 = a2^n + 2b + 1. We solve g(n) = a2^n + b = a2^n + 2b + 1 for b and get b = -1. Now we need to solve for a using the boundary condition. g(1) = 1 = a2^1 - 1. In this case, a = 1 and therefore g = 2^n - 1, as we guessed.
Does this example show the method to use to solve your problem?

Related

Find formula to describe recursion in method

I am struggling with writing the formula that describes the recursive nature of the foo method.
The problem is that as far as I can tell, since every time n is divided with 2,
the binary tree formula should apply here.
This says that when in each call we divide the data we get a formula like this:
And then if we analyze for 2 so :
We get:
Which means that C(N) = log(N + 1), namely O(logN)
That all makes sense and seems to be the right choice for the foo method but it cant be because for
n = 8 I would get 3 + 1 iterations that are not n + 1 = 8 + 1 = 9 iterations
So here is your code:
void foo(int n) {
if (n == 1) System.out.println("Last line I print");
if (n > 1) {
System.out.println("I am printing one more line");
foo(n/2);
}
}
We can write a recurrence relation down for its runtime T as a function of the value of the parameter passed into it, n:
T(1) = a, a constant
T(n) = b + T(n/2), b constant, n > 1
We can write out some values of T(n) for various values of n to see if a pattern emerges:
n T(n)
---------
1 a
2 a + b
4 a + 2b
8 a + 3b
...
2^k a + kb
So for n = 2^k, T(n) = a + kb. We can solve for k in terms of n as follows:
n = 2^k <=> k = log(n)
Then we recover the expression T(n) = a + blog(n). We can verify this expression works easily:
a + blog(1) = a, as required
a + blog(n) = b + (a + blog(n/2))
= b + (a + b(log(n) - 1)
= b + a + blog(n) - b
= a + blog(n), as required
You can also use mathematical induction to do the same thing.

Time complexity of the program using recurrence relation

This program calculate fibonacci numbers. I want to find out its time complexity using recurrence relation.
Fib(n)
if n<=1
return n
else
x= Fib(n-1)
y= Fib(n-2)
return x+y
The recurrence equation for this program is
T(n)=T(n-1)+T(n-2)+c
I tried to expend it , but couldn't find the solution.
=2T(n-1)+T(n-3)+c+c
=3T(n-3)+2T(n-4)+c+c+3c
=5T(n-4)+3T(n-3)+c+c+3c+5c
-------------------------
-------------------------
-------------------------
You need to think about how many calls you make to your function.
Each call makes 2, so it makes a binary tree:
n
(n-1)--------------(n-2)
(n-2)--(n-3)------(n-3)---(n-4)
and so on.
Consider the level of the tree when you first reach 1 and ignore everything below.
This happens on level n/2 (since the lowest number of each level is the rightmost and it always decreases by 2).
It's clear that the nodes on each level up to n/2 are always twice as many as on the previous level.
Thus the total number of nodes is 1 + 2 + 2^2 + ... + 2^(n/2) = 2^(n/2+1) - 1 = O(2^(n/2))
This means that the time complexity is at least exponential.
You can probably compute it even more accurately, but for all practical purposes this should be enough to avoid this implementation.
The given recurrence relation is,
T(n) = T(n-1) + T(n-2) + c ------ 1
T(n-1)= T(n-2) + T(n-3) + c ------ 2
1-2 -> T(n) = 2T(n-1) - T(n-3) ----- 3
T(n) - 2T(n-1) + T(n-3) = 0 ----- 4
The characteristic equation of 4 is x3 - 2x2 + 1 = 0 ---- 5
Solve equation 5,
The solutions are x = 1, x = (1 + √5)/2 and x = (1 −√5)/2
There for the general solution is,
Tn = a((1 + √5)/2)n + b((1 - √5)/2)n + c . 1n
There for Tn = a((1 + √5)/2)n + b((1 - √5)/2)n + c
Let us assume T(0) = 0, from equation 1 we get T(1) = c and T(2) = 2c
There for,
T(0) = a + b + c = 0 ---- 6
T(1) = a((1 + √5)/2) + b((1 - √5)/2) + c = c
There for a((1 + √5)/2) + b((1 - √5)/2) = 0 ----- 7
T(2) = a((1 + √5)/2)2 + b((1 - √5)/2)2 + c = 2c
There for a((1 + √5)/2)2 + b((1 - √5)/2)2 = c ---- 8
solve 6, 7 and 8, to get the values of a, b and c.
The general solution is,
Tn = a((1 + √5)/2)n + b((1 - √5)/2)n + c
since (1 + √5)/2 < 2,
T(n) = O(2n).
The thing to note about your recurrence relation is that it's the same as the Fibonacci recurrence itself. This means that you're doing c units of work times whatever Fibonacci number you're calculating. You can see it yourself from the first few steps that you computed. The c's start growing like the Fibonacci numbers.
Basically your recurrence comes down to O(Fib(n)). Fibonacci numbers are exponential in n, so you're going to do exponential work.
A better way to do this is to remember one of the numbers. Like this:
Fib(n):
if n <= 2:
return 1,0
else:
x,y = Fib(n-1)
return x+y,x
So when you call Fib(n), you're getting two values, Fib(n) and Fib(n-1). That extra x that you return "remembers" Fib(n-2) so you don't have to compute it twice. This recurrence comes down to T(n) = T(n-1) + c, which is O(n).
Once you have that, you can reduce this to a nice little for loop:
x = 1, y = 0
for i from 3 to n:
x,y = x+y,x

Can not figure out complexity of this recurrence

I am refreshing on Master Theorem a bit and I am trying to figure out the running time of an algorithm that solves a problem of size n by recursively solving 2 subproblems of size n-1 and combine solutions in constant time.
So the formula is:
T(N) = 2T(N - 1) + O(1)
But I am not sure how can I formulate the condition of master theorem.
I mean we don't have T(N/b) so is b of the Master Theorem formula in this case b=N/(N-1)?
If yes since obviously a > b^k since k=0 and is O(N^z) where z=log2 with base of (N/N-1) how can I make sense out of this? Assuming I am right so far?
ah, enough with the hints. the solution is actually quite simple. z-transform both sides, group the terms, and then inverse z transform to get the solution.
first, look at the problem as
x[n] = a x[n-1] + c
apply z transform to both sides (there are some technicalities with respect to the ROC, but let's ignore that for now)
X(z) = (a X(z) / z) + (c z / (z-1))
solve for X(z) to get
X(z) = c z^2 / [(z - 1) * (z-a)]
now observe that this formula can be re-written as:
X(z) = r z / (z-1) + s z / (z-a)
where r = c/(1-a) and s = - a c / (1-a)
Furthermore, observe that
X(z) = P(z) + Q(z)
where P(z) = r z / (z-1) = r / (1 - (1/z)), and Q(z) = s z / (z-a) = s / (1 - a (1/z))
apply inverse z-transform to get that:
p[n] = r u[n]
and
q[n] = s exp(log(a)n) u[n]
where log denotes the natural log and u[n] is the unit (Heaviside) step function (i.e. u[n]=1 for n>=0 and u[n]=0 for n<0).
Finally, by linearity of z-transform:
x[n] = (r + s exp(log(a) n))u[n]
where r and s are as defined above.
so relabeling back to your original problem,
T(n) = a T(n-1) + c
then
T(n) = (c/(a-1))(-1+a exp(log(a) n))u[n]
where exp(x) = e^x, log(x) is the natural log of x, and u[n] is the unit step function.
What does this tell you?
Unless I made a mistake, T grows exponentially with n. This is effectively an exponentially increasing function under the reasonable assumption that a > 1. The exponent is govern by a (more specifically, the natural log of a).
One more simplification, note that exp(log(a) n) = exp(log(a))^n = a^n:
T(n) = (c/(a-1))(-1+a^(n+1))u[n]
so O(a^n) in big O notation.
And now here is the easy way:
put T(0) = 1
T(n) = a T(n-1) + c
T(1) = a * T(0) + c = a + c
T(2) = a * T(1) + c = a*a + a * c + c
T(3) = a * T(2) + c = a*a*a + a * a * c + a * c + c
....
note that this creates a pattern. specifically:
T(n) = sum(a^j c^(n-j), j=0,...,n)
put c = 1 gives
T(n) = sum(a^j, j=0,...,n)
this is geometric series, which evaluates to:
T(n) = (1-a^(n+1))/(1-a)
= (1/(1-a)) - (1/(1-a)) a^n
= (1/(a-1))(-1 + a^(n+1))
for n>=0.
Note that this formula is the same as given above for c=1 using the z-transform method. Again, O(a^n).
Don't even think about Master's Theorem. You can only use Masther's Theorem when you're given master's theorem when b > 1 from the general form T(n) = aT(n/b) + f(n).
Instead, think of it this way. You have a recursive call that decrements the size of input, n, by 1 at each recursive call. And at each recursive call, the cost is constant O(1). The input size will decrement until it reaches 1. Then you add up all the costs that you used to make the recursive calls.
How many are they? n. So this would take O(2^n).
Looks like you can't formulate this problem in terms of the Master Theorem.
A good start is to draw the recursion tree to understand the pattern, then prove it with the substitution method. You can also expand the formula a couple of times and see where it leads.
See also this question which solves 2 subproblems instead of a:
Time bound for recursive algorithm with constant combination time
May be you could think of it this way
when
n = 1, T(1) = 1
n = 2, T(2) = 2
n = 3, T(3) = 4
n = 4, T(4) = 8
n = 5, T(5) = 16
It is easy to see that this is a geometric series 1 + 2+ 4+ 8 + 16..., the sum of which is
first term (ratio^n - 1)/(ratio - 1). For this series it is
1 * (2^n - 1)/(2 - 1) = 2^n - 1.
The dominating term here is 2^n, therefore the function belongs to Theta(2^n). You could verify it by doing a lim(n->inf) [2^n / (2^n - 1)] = +ve constant.
Therefore the function belongs to Big Theta (2^n)

Big O Question - Algorithmic Analysis III

I have the following question:
Solve the recurrence relation simplifying the answer using Big 'O' notation:
f(0) = 2
f(n) = 6f(n-1)-5, n>0
I know this is a first order inhomogenous recurrence relation and have had a go at the question but I cannot seem to get the right output for the base case (f(0) = 2).
The question MUST use the sum of geometric series forumla within the proof.
Here is my answer - Note sum(x = y, z) is a replacement for capital sigma notation, where x is the lower bound of the summation initialised to y and z is the upper bound of the summation:
1. *change forumla:*
2. f(n) = 6^n.g(n)
3. => 6^n.g(n) = 6.6^(n-1) .g(n-1) -5
4. => g(n) = g(n-1)-5/6^n
5. => g(n) = sum(i=1, n)-5/6^i
6. => f(n) = 6^n.sum(i=1, n)-5/6^i
7. => *Evaluate the sum using geometric series forumla*
8. => sum(i = 1, n)-5/6^i = [sum(i = 1, n)a^i] -------> (a = -5/6)
9. => *sub a = -5/6 into geometric forumla [a(1-a^n)/(1-a)]*
10. => [(-5/6(1 - (-5/6)^n))/(1-(-5/6))]
11. => g(n) = [(-5/6(1 + (5/6)^n))/(1+5/6)]
12. => f(n) = 6^n . g(n) = 6^n[(-5/6(1 + (5/6)^n))/(1+5/6)]
13. => *sub in n = 0 to see if f(0) = 2*
Firstly, I am sure the equation on line 11 can be simplified further and secondly subbing in n = 0 should yield 2 as the result. I cannot obtain this answer when reaching line 13...
EDIT: What I need to know is why I am not getting f(0) = 2 when subbing n = 0 into the equation in line 12. Also what I would like to know is how can I simplify the equation for f(n) in line 12?
Anyone...?
Without thinking too hard about this, I'm going to say that f(n + 1) is 6 times larger than f(n), minus a constant. f(n) is therefore certainly O(6^n). Although you may find a tighter bound, that's about as far as I'd go in practice!
For the fun of it, I'll try this:
f(1) = 6f(0) - 5
= 6^1.f(0)
f(2) = 6f(1) - 5
= 6(6f(0) - 5) - 5
= 6^2.f(0) - 6^1.5 - 5
f(3) = 6f(2) - 5
= 6^3.f(0) - 6^2.5 - 6^1.5 - 5
I'll hazard a guess that
f(n) = 6^n.f(0) - 5.(6^0 + 6^1 + ... + 6^(n-1))
and I'm pretty sure that I could prove this by induction in a few lines (exercise left as an exercise for the student).
Now,
sum (k in 0..n-1) 6^k = (1 - 6^n) / (1 - 6)
therefore
f(n) = 6^n.f(0) - 5.(1 - 6^n) / (1 - 6)
= 6^n.f(0) + (1 - 6^n)
= 6^n.(2 - 1) + 1
= 6^n + 1
confirming my earlier intuition.
Let's just do a few quick check calculations:
f(0) = 2 = 6^0 + 1
f(1) = 6.2 - 5 = 7 = 6^1 + 1
f(2) = 6.7 - 5 = 37 = 6^2 + 1
f(3) = 6.37 - 5 = 237 = 6^3 + 1
That's enough for me for homework :-)

Solving a recurrence relation

I'm not sure if this is the right place to post this, but the problem actually belongs to a programming assignment. This recursion is something I probably should know how to solve but Im having a bit of trouble with it.
Solve the recursion:
T(0) = 2;
T(n) = T(n-1) + 2;
Solution:
T(n) = 2(n+1)
Could someone please show me how they got to that solution?
Please not that its not the main part of the assignment to solve this particular problem.
You have to figure out what is solution and then you can use induction, to prove it.
To figure solution is simple.
Value is previous value + 2.
2, 2+2, 2+2+2, 2+2+2+2, 2+2+2+2+2, ...
Use induction to prove:
T(0) = 2
T(n) = T(n-1) + 2;
Solution
T(n) = 2(n+1)
Proof:
T(n) = T(n-1) + 2 => 2((n-1)+1) + 2 = 2(n+1)
Check for n=0
2(0+1)=2
End of proof
Try writing out the first few values - it should then be obvious.
Take T(5):
T(5)
|
+-> T(4) + 2
|
+-> T(3) + 2
|
+-> T(2) + 2
|
+-> T(1) + 2
|
+-> T(0) + 2
|
+-> 2
Now count the number of 2's that are added together for T(5).
Then try to figure out how many 2's would be added for T(n).
It's an arithmetic progression with ratio common difference 2.
The first term is T[0] = 2 and the ratio common difference is r = 2 so the n + 1th term (n + 1th because there are n + 1 numbers in 0, 1, 2, ..., n) is T[0] + r*(n + 1 - 1) = 2 + 2*n = 2*(n + 1).
No guessing required, just recognize it as an arithmetic progression.
Each time n decreases by one, 2 is added. This gives a variable term of 2n. Since T(0) is fixed at 2, this gives a constant term of 2. Adding them together gives 2n + 2, or 2(n + 1).
I'd solve it as follows:
Assume that T(n) = a*n + b for some a and b.
T(0) = 2. So a * 0 + b = 2, thus b = 2.
T(n) = T(n-1) + 2, so
a * n + b = (a * (n-1) + b) + 2 consequently
a * n + b = a * n - a + b + 2 and
0 = - a + 2, thus a = 2.
So we have T(n) = 2 * n + 2 = 2 (n+1).
This one is pretty straightforward to solve by hand as the other answers point out, but in case it's ever useful, Mathematica is pretty good solving recurrence relations like this.
Evaluating
RSolve[{T[0] == 2, T[n] == T[n-1] + 2}, T[n], n]
returns
{{T[n] -> 2 (1 + n)}}
It can, for example, find the closed form of the nth Fibonacci number as well:
RSolve[{F[1] == 1, F[2] == 1, F[n] == F[n-1] + F[n-2]}, F[n], n] //FunctionExpand
returns
{{F[n] -> (((1 + Sqrt[5])/2)^n - (2/(1 + Sqrt[5]))^n*Cos[n*Pi])/Sqrt[5]}}

Resources