3

I've been trying to calculate the complexity of the following function:

k=n;
while(k>0)
  g(n);
  k=k/2; {Comment: this is integer division, so 1/2=0}
end while;
for(j=0;j<m;j++)
  f(m);

Specifically, the complexity of the while loop.I am told that g(n)'s complexity is O(n), but I'm not sure what the complexity would be for it, and how I would work it out. I have come to realise that the complexity would not be O(0.5n^2), but am unsure how to calculate it, because of the halving each time. Anyone have any ideas?

user1899174
  • 279
  • 1
  • 5
  • 12
  • If your problem size is halving each iteration, how many iterations do you need to do to reach problem size of 0? I.e. given a number `n`, how many times do you need to press /2 on your (integer) calculator to reach 0? – Karel Petranek Jan 16 '13 at 22:25
  • @Karel I've tried it for a number such as 8, which gives n/2, but a number such as 20 give n/4, so I am unsure. – user1899174 Jan 16 '13 at 22:27
  • That number is actually called a logarithm (of base 2, as you're dividing by 2). I.e. the outer loop is repeated log(n) times, the rest should be easy :) Also see http://cs.stackexchange.com/questions/581/intuition-for-logarithmic-complexity – Karel Petranek Jan 16 '13 at 22:30
  • @KarelPetranek I looked at that link, but if it is repeats log n times, how come when I use 10 as my value for n, I calculate it should run 4 times, but I get log(10) = 3.32? – user1899174 Jan 16 '13 at 22:40
  • You cannot run a loop 3.32 times so you always need to round the numbers up (fraction of an iteration in theory means you need to do whole iteration in practice). – Karel Petranek Jan 16 '13 at 23:24

3 Answers3

4

If g(n) is O(n), then your complexity is O(n*log(n))

To explain further, let us ignore g(n) for the moment

k = n;
while(k > 0) {
    k = k / 2;
}

Let say n = 1000

Then we will get the following values of k

Pass | k
-------------
 0   | 1000
 1   | 500
 2   | 250
 3   | 125
 4   | 62
 5   | 31
 6   | 15
 7   | 7
 8   | 3
 9   | 1
 10  | 0 (stopped)

log(1000) = 9.96 Note it only took 10 iterations to bring down k to zero. This is an example of a log(n) computational complexity.

Then when you add the g(n) inside the loop, that means you add O(n) for every iteration, which gives us a grand total of O(n*log(n))

Kirk Backus
  • 4,776
  • 4
  • 32
  • 52
2

The complexity of the while loop is clearly O(n log n). There are log n iterations because at the end of each iteration k is divided by 2. To get the number of iterations, express n as a power of two, say 2^x. If 2^x=n, then x = log n. That is why the complexity of the while loop is O(n log n). Don't get confused because n does not have be a power of 2, what implies that log n is not always an integer and you should write, instead of log n, [log n], where [y] is the integer part of y. You can always express [log n] as a c* log n, where c is a constant, which does not change complexity of an algorithm. Therefore, you don't need [] function and O(n log n) is acceptable and correct answer.

Complexity of the for loop depends on the complexity of f(m). If O(f(m)) is O(1), then the loop is O(m), but if O(f(m)) is O(m), then the loop is O(m^2). Because f(m) is also a part of the algorithm, you need to know the complexity of f() if you want to be certain about complexity of the entire code.

Milos
  • 518
  • 7
  • 22
0

The complexity of your algorithm is:

Your first loop runs O(logn) times and each iteration has to do g(n). Thus it takes

O(sum{i from 0 to log(n)}{O(g(i))}). 

The second loop runs m times. It takes:

O(sum{j from 0 to m}{O(f(i))})

Total complexity of your algorithm is:

O(sum{i from 0 to log(n)}{O(g(i))}) + O(sum{j from 0 to m}{O(f(i))})
xenteros
  • 15,586
  • 12
  • 56
  • 91