How to derived solution by Big'O Notation with Algorithm Efficiency? - algorithm

I was been given with this algorithm and I was told to provide its efficiency in Big'O Notation and explained the derivation.
I have tried to research about Big'O Notation and algorithm efficiency but still I am not able to solve the following question. These are the algorithms given:
i= 100
loop( i > 10)
num = 1;
loop( num < = 1000)
num = i*num
end loop
i= i /2;
end loop
I hope anyone could help me with this question, this is an exercise not homework.
Thank you.

if initial value of i - N, here 100, and max allowed value of num - M is the input, then the answer is log(N)*log(M).
So, outer loops will be executed log(N, 2) times. And inner loop will be executed log(M, current_value_of_i) times.
EDIT: to answer SilverArcher's comment.
During one iteration of the outer loop, the inner loop can't be executed more than log(1000,11) times.

Notice that this code always does exactly the same thing every time - there's no inputs you can change to cause it to run for a longer or shorter amount of time. As a result, the time complexity is O(1), since the runtime is independent of the size of the input.

Related

How is this nested loop algorithm analyzed?

So i have this algorithm analysis from my lecturer i need some help why the outer loop is n - 1 , isn't it should be n - 2? and the inner loop should be log3 (n) instead of log3(n) + 1
for(int a=3; a<=n; a++) n+1-2 = n-1
for(int a=1; a<n; a=a*3) log3 (n) +1
System.out.println(a); log3 (n)
Total =(n - 1)* (log3 (n)+1+log3 (n))
=(n-1)*(2 log3(n) + 1)
=2(n log3(n))+n -1 – 2 log3(n)
=n log3(n) + n – log3(n)
Is this correct answer for algorithmn analysis? thats what my lecturer showed me. Anyone can explain to me?
If you want a very precise count of the operations, it's important to specify: what operations are you counting? Number of increments a++? Number of comparisons a<=n? Number of executions of the loop body?
If you don't specify which operation you're counting, then there is not much sense in worrying about an extra +1 or -1.
Note that the variable used as counter for the outer loop is called a and the variable used as counter for the inner loop is also called a. While this is possible to do in C++, I strongly recommend not doing it. It's confusing and a good source of errors.
The outer loop is going to run for n-2 iterations. The inner loop is going to run for ceil(log3(n)) iterations (where ceil is the ceiling function). The line System.out.println(a) is not a loop, it's just one line of code, so you could write "1" on that line if you wanted; there is not much sense in writing "log3(n)" here.
The total number of times the line System.out.println(a) is executed is thus:
(n - 2) ceil(log3(n)).
It is possible that you might want to count the exact number of characters written. Again, we're coming back to the fact that you didn't specify what it is that you were counting. The number of characters depends on the exact value of a, so it changes at each iteration of the loop. But all in all, each call to System.out.println(a) prints about log10(n) characters, since we're writing in decimal.

How to calculate time complexity of existing code in production [duplicate]

This question already has answers here:
Big O, how do you calculate/approximate it?
(24 answers)
Closed 2 years ago.
I have gone through a couple of examples in understanding the time complexity of a program using the operation count and step count technique but these examples are small and straight. However in real-world programming, if someone gives you the production or live code to find the worst case time complexity of it. How does one start analyzing it?
Is there any technique or thumb rules for analyzing the program? say I have a function as shown below that has if and for conditions. For some values of n, it goes deep but for some values, it does not.
So maximum number of operations is the worst case and the minimum number of operations is the best case.
How can we know when do maximum operations occur if we have this kind of conditional statement? (Other functions can go much deeper conditional and not the loops)
int l = 0;
while (l <= n){
int m = l + (n-l)/2;
if (arr[m] == x) return;
if (arr[m] < x) l = m + 1;
else n = m - 1;
}
How does one calculate the worst and best case by looking at the above code? Do the perform step count for the above program and by substituting n = 1 till 20 and get some values and then trying to derive the function? I would like to know how do people analyze time complexity for existing code when they have this kind of branching statements.
Step by Step analysis or Set of statements to follow to solve the above problem would be greatly helpful.
As each time half of the n is added to m and the loop will be continued by increasing a unit of l or changing the value of the n to the m-1 the following scenario can give the maximum operation:
In each iteration, the `else` part is happened and set `n` to `m-1`.
Let see what is happened for this case. As each time n is dividend by 2, and l is keeping 0, after O(log(n)) iteration, l == n.
Therefore, the time complexity of the loop is O(log(n)).
Notice that other cases can increase l faster towards n. For example, if l = m + 1 it means that l = (n-1)/2, and in the next iteration, m will be increased to n-1. Hence, just 2 iteration we will have to reach to the end of the loop.

Big O sum of integers runtime

I have am trying to learn Big O and am confused on an algorithm I just came across. The algorithm is:
void pairs(int[] array){
for (int i=0; i < array.length; i++){
for (int j=i+1; j<array.length; j++){
System.out.println(array[i]+","+array[j]);
}
}
}
I think the first for loop is O(n) and I know the second for loop is O(1/2*n(n+1)). The answer to the problem was that the run time for the function is O(n^2). I simplified O(1/2*n(n+1)) to O(1/2*(n^2+n)). So I'm confused because I thought that you needed to multiply the two run time terms since the for loop is nested, which would give O(n) * O(1/2*(n^2+n)). I simplified this to O(1/2n^3 + 1/2n^2). From what I understand of Big O, you only keep the largest term so this would reduce to O(n^3). Can anyone help me out with where I went wrong? Not sure how the answer is O(n^2) instead of O(n^3).
When you say the inner loop is O(1/2*n(n+1)), you are actually describing the big-O complexity of both loops.
To say that the outer loop has complexity O(N) basically means its body runs N times. But for your calculation of the inner loop's complexity, you already took account of all iterations of the outer loop, because you added up the number of times the inner loop runs over all iterations of the outer loop. If you multiply again by N, you would be saying that the outer loop itself is re-run another N times.
Put another way, what your analysis shows is that the inner loop body (the System.out.println call) runs 1/2*n(n+1) times overall. That means the overall complexity of the two-loop combination is O(1/2*n(n+1)) = O(n^2). The overall complexity of the two-loop combination describes how many times the innermost code is run.
your mistake is counting the second loop as O(1/2n^2)...
first, you can clearly see it is capped to N-1 (when j = 0)
first loop is clearly N
Second loop is MAX of N-1...
threrefore, O(N^2)...
if we examine it little more,
second loop will run N-1 when i=0,
then N-2 for i=1,
and ONE single time for i=n-1,
this is 1/2n(n-1) = 1/2n^2 - 1/2n = O(n^2)
Notice this includes all iteration of the outer loop too!

How many times a while loop get executed?

Yesterday I applied for computer engineering master degree and it was the one of the their questions. I could not solve it so I was very curious.
...
i = 1;
while (i <= n)
{
i = i * 2;
}
...
How many times will this while loop get executed, please give your answer as a formula. For ex: log n...
Thanks
On the xth iteration of the loop, i equals 2x (you can easily prove this by induction). Suppose the loop stops after X iterations, which means n < 2X. This also means that on iteration X-1 the loop was still running and so 2X-1 &leq; n. In other words :
2X-1 &leq; n < 2X
From there, finding X as a function of log2(n) is easy.

How to calculate worst case analysis of this algorithm?

sum = 0;
for(int i = 0; i < N; i++)
for(int j = i; j >= 0; j--)
sum++;
From what I understand, the first line is 1 operation, 2nd line is (i+1) operations, 3rd line is (i-1) operations, and 4th line is n operations. Does this mean that the running time would be 1 + (i+1)(i-1) + n? It's just these last steps that confuse me.
To analyze the algorithm you don't want to go line by line asking "how much time does this particular line contribute?" The reason is that each line doesn't execute the same number of times. For example, the innermost line is executed a whole bunch of times, compared to the first line which is run just once.
To analyze an algorithm like this, try identifying some quantity whose value is within a constant factor of the total runtime of the algorithm. In this case, that quantity would probably be "how many times does the line sum++ execute?", since if we know this value, we know the total amount of time that's spent by the two loops in the algorithm. To figure this out, let's trace out what happens with these loops. On the first iteration of the outer loop, i == 0 and so the inner loop will execute exactly once (counting down from 0 to 0). On the second iteration of the outer loop, i == 1 and the inner loop executes exactly twice (first with j == 1, once with j == 0. More generally, on the kth iteration of the outer loop, the inner loop executes k + 1 times. This means that the total number of iterations of the innermost loop is given by
1 + 2 + 3 + ... + N
This quantity can be shown to be equal to
N (N + 1) N^2 + N N^2 N
--------- = ------- = --- + ---
2 2 2 2
Of these two terms, the N^2 / 2 term is the dominant growth term, and so if we ignore its constant factors we get a runtime of O(N2).
Don't look at this answer as something you should memorize - think of all of the steps required to get to the answer. We started by finding some quantity to count, and then saw how that quantity was influenced by the execution of the loops. From this, we were able to derive a mathematical expression for that quantity, which we then simplified. Finally, we took the resulting expression and determined the dominant term, which serves as the big-O for the overall function.
Work from inside-out.
sum++
This is a single operation on it's own, as it doesn't repeat.
for(int j = i; j >= 0; j--)
This loops i+1 times. There are several operations in there, but you probably don't mean to count the number of asm instructions. So I'll assume for this question this is a multiplier of i+1. Since the loop contents is a single operation, the loop and its block perform i+1 operations.
for(int i = 0; i < N; i++)
This loops N times. So as before, this is a multiplier of N. Since the block performs i+1 operations, this loop performs N(N+1)/2 operations in total. And that's your answer! If you want to consider big-O complexity, then this simplifies to O(N2).
It's not additive: the inner loop happens once for EACH iteration of the outer loop. So it's O(n2).
By the way, this is a good example of why we use asymptotic notation for this kind of thing -- depending on the definition of "operation" the exact details of the count could vary pretty widely. (Like, is sum++ a single operation, or is it add sum to 1 giving temp; load temp to sum?) But since we know that all that can be hidden in a constant factor, it's still going to be O(n2).
No; you don't count a specific number of operations for each line and then add them up. The entire point of constructions like 'for' is to make it possible for a given line of code to run more than once. You're supposed to use thinking and logic skills to figure out how many times the line 'sum++' will run, as a function of N. Hint: it runs once for every time that the third line is encountered.
How many times is the second line encountered?
Each time the second line is encountered, the value of 'i' is set. How many times does the third line run with that value of i? Therefore, how many times will it run overall? (Hint: if I give you a different amount of money on several different occasions, how do you find out the total amount I gave you?)
Each time the third line is encountered, the fourth line happens once.
Which line happens most often? How often does it happen, in terms of N?
So guess what interest you is the sum++ and how many time you execute it.
The final stat of sum would give you that answer.
Actually your loop is just:
Sigma(n) n goes from 1 to N.
Which equal to: N*(N+1) / 2 This give you in big-o-notation O(N^2)
Also beside the name of you question there is no worst case in you algorithm.
Or you could say that the worst case is when N goes to infinity.
Using Sigma notation to represent your loops:

Resources