How to calculate complexity of an algorithm? - algorithm

I've trying to calculate complexity of an algorithm, but I'm not sure how to do that. I know how to solve simple algorithms, but I'm struggling with recursion.
There is the code of recursion:
static int F(int m, int n)
{
if (n == 0)
return m;
if (m == 0 && n > 0)
return n;
else
return Math.Min((1 + F(m - 1, n)), Math.Min((1 + F(m, n - 1)), (D(m - 1, n - 1) + F(m - 1, n - 1))));
}
Can someone explain me or help me to calculate this function? I've tried googling it but I can find only simple examples.(maybe mine code is also simple?)
Thank you!

I don't know what the D function is in your first piece of code. I'll consider it as a constant function.
The first piece of your code is equivalent to the following one.
static int F(int m, int n)
{
if (n == 0 || m == 0)
return n + m;
else
return Math.Min((1 + F(m - 1, n)), Math.Min((1 + F(m, n - 1)), (D(m - 1, n - 1) + F(m - 1, n - 1))));
}
It's a little difficult to calculate the time complexity of a recursive function with two parameters, but we can estimate it roughly. We have the following equation.
T(n, m) = T(n-1, m) + T(n, m-1) + T(n-1, m-1)
We can discover that the equation is quite similar to the recursive equation of binomial coefficient, but with even larger result. This tells us that the time complexity of the algorithm is an exponential function, which is quite slow.
But actually, you can use some tricks to reduce its time complexity to O(mn).
bool calculated[MAX_M][MAX_N];
int answer[MAX_M][MAX_N]
static int F(int m, int n)
{
if (n == 0 || m == 0)
return n + m;
else
{
if (calculated[m][n] == false)
{
answer[m][n] = Math.Min((1 + F(m - 1, n)), Math.Min((1 + F(m, n - 1)), (D(m - 1, n - 1) + F(m - 1, n - 1))));
calculated[m][n] = true;
}
return answer[m][n];
}
}
I can't quite understand what the second piece of code is going to do as there are lots of functions unprovided in your code. Maybe you can explain that a bit?

Related

Big O notations - Recursive functions

I need to find the complexity of this recursive algorithms, so, i have 3 recursive algorithms and simply just want to know the Big O Notation for them. I think i have the solution for 2 of these algorithms, just wanna check with the community.
int f1(int n)
{
if ( n<= 1)
return (1);
else
return (n *f1(n-1))
}
I think the solution of this is O(n).
int f2 (int n)
{
if(n<=1)
return(1);
else
return(n*f2(n / 2))
}
I think the solution of this is O(Log 2 (n))
int f3
{
int x, i;
if( n <= 1)
return 1;
else
{
x = f3 (n / 2);
for( i = 1 ; i <= n ; i++)
x++;
return x;
}
}
What is the complexity of this recursive algorithm, i don't have the solution for this algorithm, Can you help me?
Your first two answer is correct.
Let's do analysis for your third problem,
for each times, n is divides by 2 and we need to add x for n times,
so the complexity will be
1*n+1*n/2+1*n/4+.....+1=n(1+1/2+1/4+...)=O(n)
#codecrazers answer already covers up how to calculate the complexity step-by-step. But in general the Master-Theorem makes the problem a lot simpler.
To start, lets transform this code
int f3 (int n)
{
int x, i;
if( n <= 1)
return 1;
else
{
x = f3 (n / 2);
for( i = 1 ; i <= n ; i++)
x++;
return x;
}
}
Into a recurrence:
int f(int n)
{
if( n <= 1)
1
else
f(n / 2) + θ(n)
}
So
T(n) = T(n / 2) + θ(n)
T(n <= 1) = 1
Which is case 3, thus yielding
T(n) = θ(n)

What is the time complexity of a function with two parameters?

What is the time complexity of the following method? Two parameters give me lots of confusion. Thanks in advance.
public int count(int m, int n) {
if(m == 1 || n == 1) return 1;
return count(m-1, n) + count(m, n-1);
}
This is in O(2^(n+m)).
It can be proven using induction, where the induction step is:
T(n,m) = T(n-1,m) + T(n, m-1) =(*) 2^(n+m-1) + 2^(n+m-1) = 2*2^(n+m-1) = 2^(n+m)
Where (*) is the induciton hypothesis.

Calculating time complexity of algorithm

How to calculate time complexity of function f?
void f(int n)
{
if (n <= 1)
return;
g(n, n / 3);
}
void g(int n, int m)
{
int i = 1;
while (m < n) {
m += i;
i++;
}
f(n / 2);
}
The answer is sqrt(n), but I don't see how...
Thanks
First, note that the the program can be translated now to a single function program, by inlining g(n,m) in f():
void f(int n)
{
if (n <= 1)
return;
m = n/3;
while (m < n) {
m += i;
i++;
}
f(n / 2);
}
The inner loop runs in O(sqrt(n)) iteration, because it starts from n/3, ends with n, and is increased by 1,2,3,... so if we sum it we get:
n/3 + (1 + 2 + ... + i) >= n
We need to solve the above equation to find the final value of i, and we get:
1 + 2 + ... + i >= 2n/3
From sum of arithmetic progression:
i(i+1)/2 >= 2n/3
From the above inequality, we can conclude that indeed i is in O(sqrt(n)).
So, we can denote the complexity as:
T(n) = T(n/2) + O(sqrt(n))
^ ^
recursive step syntatic sugar for some function
which is in O(sqrt(n)).
Now, we can see that:
T(n) = T(n/2) + sqrt(n) = T(n/4) + sqrt(n/2) + sqrt(n) = ... =
= sqrt(1) + ... + sqrt(n/2) + sqrt(n)
And the above sum is in O(sqrt(n))
Let Fn be the time complexity of f(n) and Gn,m be the time complexity of g(n,m).
Gn,m = sqrt(n-m) + Fn / 2
Fn = Gn,n/3 = sqrt(n-n/3) + Fn / 2 = C sqrt(n) + Fn/2
So the answer is sqrt(n).

Efficiently evaluating a recursive function?

I came across with an interesting puzzle on my previous interview.
You need to implement a function which would fit the following conditions:
m, n - positive integer numbers > 0
F(m, n) = F(m-1, n-1) + F(m, n-1)
F(1, n) = 1
F(m, 1) = 1
Obviously you can write the recursive implementation:
int F(int m, int n)
{
if(m == 1) return 1;
if(n == 1) return 1;
return F(m-1, n-1) + F(m, n-1);
}
But for input data equals one billion it will run very long time because it will get 2^1000000000 iterations :)
Does anybody have any ideas how to optimize this solution?
function F(m, n)
v = 1
s = 1
k = 1
while k < m do
v = v * (n-k) / k
s = s + v
k = k + 1
end
return s
end

Algorithm to solve for f(n) = 2*( f(n-1) + f(n-2) ) mod 1000000007 [duplicate]

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
I want to generate the nth term of the sequence 1,3,8,22,60 ,164 in Order(1) or order of (nlogn)
Calculate the nth term of the sequence 1,3,8,22,60,164,448,1224…?
I have a recurrence relation f(n) = 2 * (f(n-1) + f(n-2)). I have to solve for f(k) mod 1000000007 where k is the input. The range of k is 1 <= k <= 1000000000?. I have tried implementing it through simple recursive function, but apparently it causes overflow for large k and hence I encounter a runtime error. I am new to algorithms and stuff, so need to know whether there exists concrete and efficient ways to solve such problems?
#include<stdio.h>
#define M 1000000007
long long unsigned res(long long unsigned n){
if(n==1)
return 1;
else {
if(n==2)
return 3;
else return (2*(res(n-1)%M+res(n-2)%M));
}
}
int main(){
int test;
scanf("%d",&test);
while(test--){
long long unsigned n;
scanf("%llu",&n);
printf("%llu\n",res(n));
}
getch();
return 0;
}
You can use the two following identities:
mod(a * b, p) = mod(mod(a, p) * mod(b, p), p)
mod(a + b, p) = mod(mod(a, p) + mod(b, p), p)
That gives you, assuming that mod(2, p) = 2:
mod(f(n), p) = mod(2 * mod(mod(f(n - 1), p) + mod(f(n - 2), p), p), p)
or simpler:
mod(f(n), p) = mod(mod(2 * f(n - 1), p) + mod(2 * f(n - 2), p), p)
From there it should be easy to compute f(k). And there is no need for recursion, you can do a linear resolution (this is just a variation on the fibonacci sequence).
Hint: try to keep both f(n - 1) and f(n - 2) in locals, compute f(n) from that, then update your locals and iterate.
First of all you have to define what happen for f(0) and f(1), because at some point you will reach them.
Then you can solve it moving forward instead of backward. Start from the 2 and move forward until you reach k in that way:
f(k) {
a = F0; // F0 is the predefined value f(0)
b = F1; // F1 is the predefined value f(1)
if ( k == 0 ) {
return a;
}
else if ( k == 1 ) {
returb b;
}
else {
n = 2;
while ( n < k ) {
c=2*(a+b);
a=b;
b=c;
n = n+1;
}
return c;
}
}
If you call it many times, you should consider save all the c somewhere, so you don't have to recalculate it every time.
I hope I was clear enough. Otherwise ask me again

Resources