I implemented an algorithm which takes a matrix of R rows and C columns as input.
I say that the worst case time complexity of the algorithm is
O(C√C * R^3) or O(C^1.5 * R^3)
Now someone asks me that can't it be denoted as simply O(R^3) for worst case.
I would say that since there are 2 inputs(not one) and sometimes C can be large and sometimes R can be large, so we cannot reduce it to simply O(R^3) and both C and R should be taken into account.
Is my answer correct?
If not, why?
Yes, you are right, you cannot just simply ignore any of input parameters when considering the time complexity.
As C and R in both your case is unknown, we need to consider that they can be any values thus cannot ignore anything unless specified.
In your case as mentioned the time complexity must be specified as O(C^1.5 * R^3)
Now please notice that in your case that the time complexity is decided as product of variation of input parameters, thus even if it is specified that one parameter is strictly greater than other, we cannot just ignore that. Whereas in case of addition of complexities it can be ignored.
Just for example.
If Input :
R - any number
C - any number >= R
In above case
O(R*C) = O(R*C) --> We Cannot just ignore any input parameter
O(R+C) = O(C) --> As we know C will always be greater than R
You are correct that C and R should be taken into account in your Big O expression.
Big O analysis is useful in situations where the size of your input may vary, and here the size of your input requires two parameters to describe since you say that "sometimes C can be large and sometimes R can be large".
The only way you could eliminate the C would be if C were O(1), in which case your function would grow as O(R^3), or if C were a function of R, e.g. if C = O(R), your function would grow as O(R^4.5).
Related
Problem I want to solve: if you have to do M percolations and N deleteMins on a d-heap that initially has N elements. What is the running time for d=θ(N)?
I am confused by what d=θ(N) means. θ is supposed to represent average case running time, but in this case it is used to represent the value of d.
My question: I am assuming this mean d = N so that would mean the actual heap is simply one root with all other elements connected to that one root. Is my interpretation accurate?
Big-theta notation is often used for asymptotic running time, but it's just a relationship between values and functions, and can be used in other contexts as well.
d=θ(N) means that there are constants a and b such that, when N is big enough, aN < d < bN
Obviously, you can't have d > N in this case, since the heap only has N elements, but that a constant can be arbitrarily small. You could have d = 0.1N, for example.
The phrasing of the question suggests that the asymptotic running time will be the same no matter what these constants a and b are, which is a pretty big hint as to what the answer is. You can assume that d = N, for example, and then check to make sure you get the same answer when d = 0.1N.
I thought it meant it takes a constant amount of time to run. Is that different than one step?
O(1) is a class of functions. Namely, it includes functions bounded by a constant.
We say that an algorithm has the complexity of O(1) iff the amount of steps it takes, as a function of the size of the input, is bounded by a(n arbirtary) constant. This function can be a constant, or it can grow, or behave chaotically, or undulate as a sine wave. As long as it never exceeds some predefined constant, it's O(1).
For more information, see Big O notation.
It means that even if you increase the size of whatever the algorithm is operating on, the number of calculations required to run remains the same.
More specifically it means that the number of calculations doesn't get larger than some constant no matter how big the input gets.
In contrast, O(N) means that if the size of the input is N, the number of steps required is at most a constant times N, no matter how big N gets.
So for example (in python code since that's probably easy for most to interpret):
def f(L, index): #L a list, index an integer
x = L[index]
y=2*L[index]
return x + y
then even though f has several calculations within it, the time taken to run is the same regardless of how long the list L is. However,
def g(L): #L a list
return sum(L)
This will be O(N) where N is the length of list L. Even though there is only a single calculation written, the system has to add all N entries together. So it has to do at least one step for each entry. So as N increases, the number of steps increases proportional to N.
As everyone has already tried to answer it, it simply means..
No matter how many mangoes you've got in a box, it'll always take you the same amount of time to eat 1 mango. How you plan on eating it is irrelevant, there maybe a single step or you might go through multiple steps and slice it nicely to consume it.
Wikipedia defines time complexity as
In computer science, the time complexity of an algorithm quantifies
the amount of time taken by an algorithm to run as a function of the
length of the string representing the input.
What's mean of the strong part?
I know algorithm may be treated as a function but why its input must be "the length of the string representing"?
The function in the bolder part means the time complexity of the algorithm, not the algorithm itself. An algorithm may be implemented in a programming language that has a function keyword, but that's something else.
Algorithm MergeSort has as input a list of 32m bits (assuming m 32-bit values). It's time complexity T(n) is a function of n = 32m, the input size, and in the worst case is bound from above by O(n log n). MergeSort could be implemented as a function in C or JavaScript.
The defition is derived from the context of Turing machines where you define different states. Every function which you can compute with a computer is also computeable with turing machine.(i would say that computer computes a function on the basis of turing machine)
Every fucntion is just a mapping from one domain to other domain or same domain.
Before going to Turing machines look at the concept of finite-automata.It has finite states.If your input is of length n then it's possible that it only needs two stats but it has to visit those states n times where n is legnth of the string.
Not a good sketch but look at the image below ,our final state is C , means if
end with a string in c our string will be accepted.
We use unary numberal system. We want to check if this this string gets accepted by our automata: string is 010101010
When we read 0 from A we move to B and if we read again a 0 we will move to C and if we end with 0 our string gets accepted otherwise we move to A again.
In computer you represent numbers as strings with length n and in order to compute it you have to visit each character of the string.
Turing machines work on the same way but finite-automata only is limited to regular languages. How this is a big theory
Did you ever try to think how computer computes a function 2*x where x is your input.
It's fun :D . Suppose i want to compute 20*2 and i represent this number with unary numeral system because it's easy. so we represetn 0 with , 1 with 11 , 2 with 111 and etc so if we convert 20 to unary sytem we get 1111. You can think of a turing machine or computer(not advanced) , a system with linear memory.
Suppose empty spots in your memory are presented with # .
With you input you have something like this: ###1111#### where # means empty slot in memory, with your input head of your turing machine is at first 1 so you keep moving forward until you find first # once you find this you just replace it with * which is just a helping symbol and change the right side of # with 1 now move back and change one more 1 to * and write one 1 on the right side when you find a # keep doing this and you will be left with all * on the left hand side and all 1s on the right side, Now change all *s back to 1 and you have 2*x. Here is the trace and you have 2*x where x was your input.
The point is that the only thing these machines remember is the state.
#####1111#######
#####111*1######
#####11**11#####
#####1***111####
#####****1111###
#####11111111###
Summary
If there is some input, it is expressed as a string. So you have a length of that string. Then you have a function F that maps the length of the input (as a string) to the time needed by A to compute this input (in the worst case).
We call this F time complexity.
Say we have an algorithm A. What is its time complexity?
The very easy case
If A has constant complexity, the input doesn't matter. The input could be a single value, or a list, or a map from strings to lists of lists. The algorithm will run for the same amount of time. 3 seconds or 1000 ticks or a million years or whatever. Constant time values not depending on the input.
Not much complexity at all to be honest.
Adding complexity
Now let's say for example A is an algorithm for sorting list of integer numbers. It's clear that the time needed by A now depends on the length of the list. A list of length 0 is literally sorted in no time (but checking the length of the list) but this changes if the length of the input list grows.
You could say there exists a function F that maps the list length to the seconds needed by A to sort a list of that length. But wait! What if the list is already sorted? So for simplicity let's always assume a worst case scenario: F maps list length to the maximum of seconds needed by A to sort a list of that length.
You could measure in seconds, CPU cycles, ticks, or whatever. It doesn't depend on the units.
Generalizing a bit
What with all the other algorithms? How to measure time complexity for an algorithm that cooks me a nice meal?
If you cannot define any input parameter then we're back in the easy case: constant time. If there is some input it is expressed as a string. So you have a length of that string. And - similar to what has been said above - then you have a function F that maps the length of the input (as a string) to the time needed by A to compute this input (in the worst case).
We call this F time complexity.
That's too simple
Yeah, I know. There is the average case and the best case, there is the big O notation and asymptotic complexity. But for explaining the bold part in the original question this is sufficient, I think.
Arrange the following functions in increasing order of growth rate
(with g(n) following f(n) in your list if and only if f(n)=O(g(n))).
a)2^log(n)
b)2^2log(n)
c)n^5/2
d)2^n^2
e)n^2 log(n)
So i think answer is in increasing order is
CEDAB
is it correct? i have confusion in option A and B.
i think option A should be at first place.. less one i mean so please help how to solve this.
This question I faced in algorithm course part 1 assignment (Coursera) .
Firstly, any positive power of n is always greater than log n, so E comes before C, not after.
Also, D comes after every other function, as either interpretation of 2^n^2 (could be 2^(n^2) or (2^n)^2 = 2^(2n); I could be wrong in ignoring BIDMAS though...) are exponentials of n itself.
Taking log to be base a, some arbitrary constant:
a)
b)
Thus, unfortunately, the actual order depends of the value of a, e.g. if the value of
is greater than 2, then A comes after E, otherwise before. Curiously the base of the log term in E is irrelevant (it still maintains its place).
The answer is aecbd
The easiest way to see why is to create a table with different values of n and compare amongst them. But some intuition:
a grows lesser than any others, specially c because of the log term in the power as opposed to the term itself
e is a with a n**2 term multiplied in, which is better than it being in an exponent
b is a double exponent, but still better than a quadratic power
d is the obvious worst because it grows exponentially with a quadratic power!
Why does:
O(3n)=O(2n)=O(n)
Whereas their derivatives w.r.t n being 3, 2 and 1 respectively
Asymptotic Notation has no relation with derivatives. It is actually a measure of growth of function w.r.t. size of n. So, it tells us how a function will be changed on changing the value of n. If two functions get changed in same manner on changing n in the same way, we would call them the functions of same order. For example,Let f(n)=3n2+n+1 and g(n)=5n2+3n+1
If we double the n, both functions will roughly get 4 times of previous value. Hence they both are of order O(n2). We removed the constant coefficients(5 and 3) in Big-oh notation, because they are not contributing in telling how function is growing w.r.t. n (In every case, function will get 4 times). However we didn't remove the constant 2(power or exponent of n) because it is contributing in telling how function is growing w.r.t. n(Had we removed that constant and our function would get twice instead of 4 times hence we know it is contributing). Formally, we define Big-Oh notation as follows:
See here: Definition of Big O notation
f(n)=O(g(n)), if and only if f(n)<=c.g(n) for some c>0 and n>=n0
Now let me show you how O(3n)=O(2n)=O(n)
Informal Proof:
f(n)=2n and g(n)=3n both will grow linearly w.r.t. n. By linearly, I mean that if we double/halve n, the function output will also get doubled/halved. It doesn't matter if we change the coefficient to 2,3, or 1000, it will grow linearly w.r.t n. So, that's why O(n)=O(2n)=O(3n)Notice that it is not about removing constants, it's about whether these constants contribute in telling about how our function is growing w.r.t. n.
As a counter-example for this, Let's suppose
f(n)=2n andg(n)=22n
We can't remove the 2 in exponent because that 2 is contributing and saying that g(n) will actually change in terms of square w.r.t. how f(n) would change.So,f(n)=O(2n)while g(n)=O(4n)
Formal Proof:
Suppose n is sufficiently largeif f(n)=O(n), g(n)=O(2n) and h(n)=O(3n) then f(n)<=c1n for some c1>0g(n)<=2c2n for some c2>0, let's have c3=2c2 hence g(n)<=c3n or g(n)=O(n) or O(2n)=O(n)Similarly h(n)<=3c4n or h(n)=O(n) or O(3n)=O(n)Hence, O(3n)=O(2n)=O(n)
Final Words:The key point is just to check how a function is growing. After practicing, you'd have some idea like anp+bnp-1+...+c = O(np)And many more.Read CLRS Book. I don't remember exactly but I think Chapter-3 is dedicated for this concept.