tags:

views:

82

answers:

3

I've a simple but confusing doubt about whether the program below runs in exponential time. The question is : given a +ve integer as input, print it out. The catch is that you deliberately do this in a loop, like this:

int input,output=0;
cin >> input;
while (input--) ++output; // Takes time proportional to the value of input
cout << output;

I'm claiming that this problem runs in exponential time. Because, the moment you increase the # of bits in input by 1, the program takes double the amount of time to execute. Put another way, to print out log2(input) bits, it takes O(input) time.

Is this reasoning right?

+2  A: 

You have kind of answered your own question:

// Takes time proportional to the value of input

This is exactly what happens. If you double the input you double the time taken. If you triple it you triple time taken.

ie. cost = constant * input_size

Which you can see is a linear relationship for input_size.

An exponential relationship would be something like:

cost = constant * (input_size)^x

Where it is X you vary. This is not the case here.

filip-fku
No, that's just the problem- it *appears* linear, but it isn't. The reason is that the running time depends on the *value* of the input, not on the *size* of the input. (For comparison, bubble sort takes O(n^2) time where n is the *size* of the input - it doesn't matter what the numbers you give are).
Ganesh
@user: the `while (input--)` is equivalent to `for (int i=0; i<input; i++)` which is equivalent to iterating over a list with `input` size.
Nick D
@user bubble sort runs in O(n^2) time because for each element it goes over each other element (goes over n elements n times). This is why it is O(n^2). Here you are going over each "element" only once. Therefore linear - O(n). Also: proportional to value of input means exactly this. And you have said it yourself!
filip-fku
@Nick : Well, there's no list of length n here! I'm making a loop up when it isn't needed at all! @flip-fku: That's the problem.. here it's a question of the *value* of the input, in bubble sort it's a question of the *size* of the input. That's a big difference.
Ganesh
@user: I don't think I agree. The cost is a function of the number of times you have to repeat an operation. In your example, the number of times you have to do the operation (print value) is the same as the value of the number input. Therefore the value of the input also doubles as the size of the input the way you describe it. I think we are getting confused because of the interpretation of example itself. In principle we probably agree.Think of it this way: You have a list of N numbers ranging from 1 to N. You want to print out each number. The cost is O(n). This is exactly your scenario.
filip-fku
A: 

I think where you are a bit confused is when you reason:

the moment you increase the number of bits in input by 1, the program takes double the amount of time to execute

This is effectively saying that when you double the size of the input, the execution time doubles. Thus, it is actually a linear relationship and would be Big O(n).

Coxy
+1  A: 

You could say it's exponential, but it still ends up being O(input) in the end.

The size of the input is O(log input). As you said, doubling the value doubles the time:

1 bits => 1 increments max
2 bits => 4 increments max
3 bits => 8 increments max
...
n bits => 2^n increments max

So the running time is O(2^log(input)) = O(input). So you could say it's exponential in the number of bits or linear in the value. It's the same thing. Usually you say it's linear in the value of input though.

IVlad
Exactly, it's exponential in the number of bits required as output. This is much more informative than saying "it's linear in input value". The reason being : compare this with knapsack problem, where you have n weights to fill in a knapsack of capacity W . Wikipedia says (http://en.wikipedia.org/wiki/Knapsack_problem) you can solve this in O(nW) time. This is again linear in each of its arguments, but is exponential in the number of output bits! Thus, my program runs in psuedo-polynomial time.
Ganesh
@user356106 - yes, you could say that. I don't agree that it's more informative however, it offers no useful extra information (at least in this case) and it just doesn't feel right to say it's exponential. In any case, strictly speaking, saying only that "it's exponential" or that "it's linear" is wrong: one must also specify what it's linear or exponential in.
IVlad
Absolutely agree! The units of reference must be stated. You could say it is exponential in the number of bits required to represent the number, or linear in the number of iterations it takes to print out from the given number to 0.
filip-fku
@filip-fku, @IVlad: True enough, the units of reference must be stated. But all said and done, running time is ultimately a function of the number of output bits! That's the most meaningful unit of reference. In any case, the *value* of the input is somewhat deceptive, as the phrase "pseudo-polynomial time" shows.
Ganesh