hi i have this recurrence: how to solve?
a) Solve the following recurrence using the iteration method and give an asymptotic running time:
T(0)=0 and T(n)=10 +T(n-1), for n ≥ 1
You can use dynamic programming technique to iteratively solve the problem:
define results[n+1];
results[0] = 0;
for (i = 1; i < n + 1 ) {
set results[i] to 10 + results[i-1]
}
Tn = results[n];
Running time for the above algorithm will n.
Related
Can anybody help me find time conplexity of this recursive function?
int test(int m, int n) {
if(n == 0)
return m;
else
return (3 + test(m + n, n - 1));
The test(m+n, n-1) is called n-1 times before base case which is if (n==0), so complexity is O(n)
Also, this is a duplicate of Determining complexity for recursive functions (Big O notation)
It is really important to understand recursion and the time-complexity of recursive functions.
The first step to understand easy recursive functions like that is to be able to write the same function in an iterative way. This is not always easy and not always reasonable but in case of an easy function like yours this shouldn't be a problem.
So what happens in your function in every recursive call?
is n > 0?
If yes:
m = m + n + 3
n = n - 1
If no:
return m
Now it should be pretty easy to come up with the following (iterative) alternative:
int testIterative(int m, int n) {
while(n != 0) {
m = m + n + 3;
n = n - 1;
}
return m;
}
Please note: You should pay attention to negative n. Do you understand what's the problem here?
Time complexity
After looking at the iterative version, it is easy to see that the time-complexity is depending on n: The time-complexity therefore is O(n).
Assuming do_something is O(1), how do I calculate the time complexity of this function?
function run(n) {
for(var i = 1; i <= n; i++) {
var counter = 1;
while(counter <= n) {
for (var j = counter; j >= 1; j--) {
do_something();
}
counter = counter * 2;
}
}
}
I'm assuming the initial for loop means the that the complexity will be n and the inner while loop means log(n). Is this true?
How do I calculate the complexity of everything?
Thanks.
It's not trivial to calculate the complexity of everything because there are functions (e. g. collatz conjecture) where no exact analysis is known. In such a case you can do an empirical analysis where you guess which run time class would match best.
Related to your sample:
The outer for loop is called n times
The while loop is called log(n) times
The inner for loop is called counter times where counter grows 2^m. But counter is recalculated log(n) times
That means the inner exponential for loop (2^m) is called m=log(n) times.
So you have 2^(log n) = n log(2) = n
You can also do it vice versa. The inner exponential function is called log times. Means log(2^m) -> (2^n = 2^m) -> m = n.
You can also simply create a sum of 2^m from m=0 to m=log(n) which is 2n-1 -> O(n).
Then you have to multiply linear time of outer for loop with linear time of while loop (incl. inner for loop). So you have O(n*n) = O(n²) time.
The exact amount of steps can be calculated.
The outer loop runs n times
The while and inner-most loop is run counter times for each of the values of counter, these are 1, 2, 4, 8, ..., 2^(bitLength(n)-1)
which sums to 2^bitLength(n) - 1
where bitLength(n) = trunc(ln(n)/ln(2))+1
Multiplying these two, yields the exact amount of steps:
n * (2^bitLength(n) - 1)
The approximate complexity is O(n2), because O(2^bitLength(n) - 1) = O(n)
I got skunked in computing the time complexity in the inner loop.
Lets consider the following case.
Case 1:
for(int i = 0; i <= n; i++) - O(n)
{
for(int j = 0; j <= i; j++) - O(?);
{
//Some thing goes here
}
}
Here the inner loop got executed every time up to value i.
So, can I tell like, the complexity for the inner loop is some O(i),
and the overall complexity is O(N) * O(I); ie: O(N*I)
Could some one explain in some brief manner, so i can able to understand the computing.
Thanks.
The overall time complexity is O(n²) (in fact, it’s even Θ(n²)).
The inner loop has complexity O(i). However, n is related to i, so simply saying that the whole thing has complexity O(ni) is wrong. The body of the inner loop will run 0 + 1 + 2 + ⋯ + n = (n² + n) / 2 = Θ(n²) times.
Before i go over what you asked for i will explain a simple example.
We caliculate the time complexity based on how many times the innermost loop is executed
consider this case:
for(i=0;i<n;i++){
for(j=0;j<n;j++){
....
}
}
here the outer loop is executed n times and in every iteration the inner loop is executed n times.
1st iteration - n
2st iteration - n
3st iteration - n
.
.
.
nth iteration -n
so the inner loop is executed n*n times.so it is O(n^2).
Now we caliculate for the case what you asked for
for(int i=0;i<=n;i++){
for(int j=0;j<=i;j++){
//Some thing goes here
}
}
Here the Outer loop is executed for n times. and in every i'th iteration the inner loop is executed i times.
1st iteration - 1
2nd iteration - 2
3rd iteration - 3
.
.
.
nth iteration -n
so when we caliculate it would be
1+2+3+.....+n = n(n+1)/2
which is basically O(n^2). :)
I have to calculate the complexity of this algorithm,I tried to solve it and found the answer to be O(nlogn). Is it correct ? If not please explain.
for (i=5; i<n/2; i+=5)
{
for (j=1; j<n; j*=4)
op;
x = 3*n;
while(x > 6)
{op; x--;}
}
Katrina, In this example we've got an O (n*log(n))
`
for (int i= 0; i < N; i++) {
c= i;
while (c > 0) {
c= c/2
}
}
How ever you have another for that includes this both bucles.
Im not quite sure to understand the way it works the algorithm but an standard way considering an another for bucle, should be O(nnlog n
for (int j= 0; i < N); j++) { --> O(n)
for (int i= 0; i < N; i++) { O(n)
c= i;
while (c > 0) { O(logn)
c= c/2 O(1)
}
}
} ?
Aftermath in this standard algorithm would be O(n) * O(n) * O(logn) * O(1)
So, I think you forgot to include another O(n)
)
Hope it helps
Let's count the number of iterations in each loop.
The outermost loop for (i=5; i<n/2; i+=5) steps through all values between 5 and n / 2 in steps of 5. It will, thus, require approximately n / 10 - 1 iterations.
There are two inner loops. Let's consider the first one: for (j=1; j<n; j*=4). This steps through all values of the form 4^x between 1 and n for integers of x. The lowest value of x for this to be true is 0, and the highest value is the x that fulfills 4^x < n -- i.e., the integer closest to log_4(n). Thus, labelling the iterations by x, we have iterations 0, 1, ..., log_4(n). In other words, we've approximately log_4(n) + 1 iterations for this loop.
Now consider the second inner loop. It steps through all values from 3 * n down to 7. Thus the number of iterations are approximately 3 n - 6.
All other operations have constant run time and can therefore be ignored.
How do we put this together? The two inner loops are run sequentially (i.e., they are not nested) so the run time for both of them together is simply the sum:
(log_4(n) + 1) + (3 n - 6) = 3 n + log_4(n) - 5.
The outer loop and the two inner loops are, however, nested. For every iteration of the outer loop, both the inner ones are run. Therefore we multiply the number of iterations of the outer with the total of the inner:
(n / 10 - 1) * (3 n + log_4(n) - 5) =
= 3 n^2 / 10 + n log_4(n) / 10 - 7 n / 2 - log_4(n) + 5.
Finally, complexity is often expressed in Big-O notation -- that is, we're only interested in the order of the run time. This means two things. First, we can ignore all constant factors in all terms. For example, O(3 n^2 / 10) becomes just O(n^2). Thereby we have:
O(3 n^2 / 10 + n log_4(n) / 10 - 7 n / 2 - log_4(n) + 5) =
= O(n^2 + n log_4(n) - n - log_4(n) + 1).
Second, we can ignore all terms that have a lower order than the term with the highest order. For example, n is of an higher order than 1 so we have O(n + 1) = O(n). Thereby we have:
O(n^2 + n log_4(n) - n - log_4(n) + 1) = O(n^2).
Finally, we have the answer. The complexity of the algorithm your code describes is O(n^2).
(In practice, one would never calculate the (approximate) number of iterations as we did here. The simplification we did in the last step can be done earlier which makes the calculations much easier.)
As Fredrik mentioned, time complexity of first and third loops are O(n). an time for second loop is O(log(n)).
So complexity of following algorithm is O(n^2).
for (i=5; i<n/2; i+=5)
{
for (j=1; j<n; j*=4)
op;
x = 3*n;
while(x > 6)
{op; x--;}
}
Note that complexity of following algorithm is O(n^2*log(n)) which is not same with above algorithm.
for (i=5; i<n/2; i+=5)
{
for (j=1; j<n; j*=4)
{
op;
x = 3*n;
while(x > 6)
{op; x--;}
}
}
I'm trying to find a loop invariant so that we can prove this program partially-correct:
{ n >= 1 } pre-condition
i = 1;
z = 1;
while (i != n) {
i = i + 1;
z = z + i*i;
}
{ z = n*(n+1)*(2*n + 1)/6 } post-condition
I am really stuck. Some of the invariants I've tried so far are:
z <= n*(n+1)*(2*n + 1)/6 ^ i <= n
and
z = i*(i+1)*(2*i + 1)/6 ^ i <= n
I would really appreciate some advice.
To find an appropriate invariant you have to have an intuition what the investigated function actually does. In your example the value i^2 is successively added to the accumulator z. So the function computes (just going through the first few iterations of the while-loop by hand and then generalizing):
1^2 + 2^2 + 3^2 + 4^2 + 5^2 + ... + n^2
or written a bit more formally
SUM_{i=1}^{n} i^2
i.e., the sum of all squares of i ranging from 1 to n.
On first sight this might not look similar to your post-condition. However, it can be shown by induction on n that the above sum is equal to
(n*(n+1)*(2*n + 1))/6
which I guess is the intended post-condition. Since we now know that the post-condition is equal to this sum, it should be easy to read off the invariant from the sum.