Which one is faster? O(2^n) or O(n!) - math

I'm studying algorithm complexity and I am trying to figure out this one question that runs in my mind- is O(n!) faster than O(2^n) or is it the opposite way around?

O(2^n) is 2 * 2 * 2 * ... where O(n!) is 1 * 2 * 3 * 4 * ...
O(n!) will quickly grow much larger - so O(2^n) is faster.
For example: 2^10 = 1024 and 10! = 3628800

You can try working with Stirling's approximation for n!
https://en.wikipedia.org/wiki/Stirling%27s_approximation
n! = (n / e)^n * sqrt(2 * Pi * n) * (1 + o(n))
Now, let's compare
O(n!) <=> O(2^n)
In order to find out the right letter <, = or > let's compute limit
lim (n! / 2^n) =
n -> +inf
lim (n / e)^n * sqrt(2 * pi * n) / 2^n >=
n -> +inf
lim n^n / (2 * e)^n >= // when n > 4 * e
n -> +inf
lim (4 * e)^n / (2 * e)^n =
n -> +inf
lim 2^n = +inf
n -> +inf
So
lim (n! / 2^n) = +inf
n -> +inf
which means that O(n!) > O(2^)

Related

Solve sigma example

I have a sigma example:
And I don't have any idea how to solve it. Can you help me with the code, please?
(Code pascal, java or c++)
Expanding the inner term, you get m^3 - 3m^2n + 3mn^2 - n^3, which yields a double summation of m^5, -3m^4n, 3m^3n^2 and -m^2n^3. These summations are separable, meaning that they are the product of a sum on m of a power of m and a sum on n of a power of n.
You can evaluate these sums by means of the Faulhaber formulas up to degree five, which are polynomial expressions. Evaluate them by Horner's method.
int F1(int n) { return (n + 1) * n / 2; }
int F2(int n) { return ((2 * n + 3) * n + 1) * n / 6; }
int F3(int n) { return ((n + 2) * n + 1) * n * n / 4; }
...
int S= F5(20) * 30 - 3 * F4(20) * F1(30) + 3 * F3(20) * F2(30) - F2(20) * F3(30);
Using the obvious method of summation, the inner loop will evaluate 30 cubes of a difference, for a total of 60 additions and 60 multiplications, and the outer loop will repeat this 20 times, with extra multiplications and additions, for a total of 1220 + and 1240 *.
Compare to the above method, performing 18 +, 30 * and 7 divisions in total (independently of the values of m and n).

How to find n in ((r^n-1)/(r-1))%p = s, if p is prime?

I thought of reducing it to this, but couldn't come up to any conclusion.
((r^n-1)/(r-1))%p == ((r^n-1)*(invmod(r-1,p)))%p.
it's also given that n should lie in between [1,p) if possible and for every r^i where i belongs [1,p) are distinct and contains all the numbers from [1,p).
Please help !
I will assume in this answer that we are talking about r^(n-1)
x % p = s
means that exists an arbitrary integer number m so that
x = p * m + s
since the % is periodic and divides numbers into modulo classes. This means that
(r ^ (n - 1)) / (r - 1) = p * m + s
where m is an arbitrary integer number. This means that
r ^ (n - 1) = (p * m + s) * (r - 1)
Since all the numbers are positive, we can turn this into logarithmic formula:
ln (r ^ (n - 1)) = ln ((p * m + s) * (r - 1))
Since power inside a logarithm is equivalent to a scalar, we can do some further modifications:
(n - 1) * ln(r) = ln ((p * m + s) * (r - 1))
so
n * ln(r) = ln ((p * m + s) * (r - 1)) + ln(r)
therefore
n * ln(r) = ln((p * m + s) * r * (r - 1))
Finally:
n = ln((p * m + s) * r * (r - 1)) / ln(r)
We can further refine this if needed:
n = log(r, (p * m + s) * r * (r - 1))
So
n = log(r, r) + log(r, (p * m + s) * (r - 1))
which is
n = 1 + log(r, (p * m + s) * (r - 1))
You will need to analyze the problem space, knowing that n, r and s are in the interval of [1, p) and m is an arbitrary integer. So, the question is: what is the set of possible integer values for m that will allow all the three values to be in the desired interval and what will the possible values be. This is a longer analysis which is outside the scope of a short SO answer, but I think you should be ok from here. If not, then ask another question where you will be stuck and let me know about it.

How to find where an equation equals zero

Say I have a function and I find the second derivative like so:
xyr <- D(expression(14252/(1+exp((-1/274.5315)*(x-893)))), 'x')
D2 <- D(xyr, 'x')
it gives me back as, typeof 'language':
-(14252 * (exp((-1/274.5315) * (x - 893)) * (-1/274.5315) * (-1/274.5315))/(1 +
exp((-1/274.5315) * (x - 893)))^2 - 14252 * (exp((-1/274.5315) *
(x - 893)) * (-1/274.5315)) * (2 * (exp((-1/274.5315) * (x -
893)) * (-1/274.5315) * (1 + exp((-1/274.5315) * (x - 893)))))/((1 +
exp((-1/274.5315) * (x - 893)))^2)^2)
how do I find where this is equal to 0?
A little bit clumsy to use a graph/solver for this, since your initial function as the form:
f(x) = c / ( 1 + exp(ax+b) )
You derive twice and solve for f''(x) = 0 :
f''(x) = c * a^2 * exp(ax+b) * (1+exp(ax+b)) * [-1 + exp(ax+b)] / ((1+exp(ax+b))^3)
Which is equivalent that the numerator equals 0 - since a, c, exp() and 1+exp() are always positive the only term which can be equal to zero is:
exp(ax+b) - 1 = 0
So:
x = -b/a
Here a =-1/274.5315, b=a*(-893). So x=893.
Just maths ;)
++:
from applied mathematician point of view, it's always better to have closed form/semi-closed form solution than using solver or optimization. You gain in speed and in accuracy.
from pur mathematician point of view, it's more elegant!
You can use uniroot after having created a function from your derivative expression:
f = function(x) eval(D2)
uniroot(f,c(0,1000)) # The second argument is the interval over which you want to search roots.
#Result:
#$root
#[1] 893
#$f.root
#[1] -2.203307e-13
#$iter
#[1] 7
#$init.it
#[1] NA
#$estim.prec
#[1] 6.103516e-05

Calculating the right number of bits in a bloom filter

I'm trying to make a configurable bloom filter. In the constructor you set the predicted necessary capacity of the filter (n), the desired error rate (p), and a list of hash functions (of size k).
According to Wikipedia, the following relation holds (m being the number of bits):
p = (1 - k * n / m) ** k
Since I get p, n and k as parameters, I need to solve for m; I get the following:
m = k * n / (1 - p ** (1 / k))
However, there are a few things that make me think I did something wrong. For starters, p ** (1 / k) will tend towards 1 for a large enough k, which means the whole fraction is ill defined (because you can conceivably divide by 0).
Another thing you may notice is that as p (the allowed maximum error rate) grows, so does m, which is totally backwards.
Where did I go wrong?
You did solve the equation correctly, however note that Wikipedia states:
The probability of all of them being 1, which would cause
the algorithm to erroneously claim that the element is in
the set, is often given as:
p ~= (1 - (1 - 1 / m) ** (k * n)) ** k ~= (1 - Exp(-k * n / m)) ** k
This is very different from what you've stated:
p = (1 - k * n / m) ** k
So what you really want to start with is
p = (1 - (1 - 1 / m) ** (k * n)) ** k
I worked this out to be
(1 - 1 / m) ** (k * n) = 1 - p ** (1 / k)
1 - 1 / m = (1 - p ** (1 / k)) ** (1 / (k * n))
m - 1 = m * (1 - p ** (1 / k)) ** (1 / (k * n))
m - m * (1 - p ** (1 / k)) ** (1 / (k * n)) = 1
m * (1 - (1 - p ** (1 / k)) ** (1 / (k * n))) = 1
m = 1 / (1 - (1 - p ** (1 / k)) ** (1 / (k * n)))

how to get modulo of a value in exponential form

Question is about the modulo operator on very large numbers.
For example consider a question where the total number of permutations are to be calculated.
Consider a number of 90 digits with each of the 9 numbers (1 to 9) repeating 10 times
so 90!/(10!)^9) is to be calculated
After reading many answers on StackOverflow I used logarithms to do it.
Now consider the log value to be 1923.32877864.
Now my question is how can I display the answer (i.e. 10 ^ log10(value) ) modulo of "m"?
And is this the best method for calculating the possible number of permutations?
Edit
Got the solution :)
Thanks to duedl0r.
Did it the way you specified using Modular Multiplicative Inverse.Thanks :)
I'm not sure whether this is actually possible and correct, but let me summarize my comments and extend the answer from Miky Dinescu.
As Miky already wrote:
a × b ≣m am × bm
You can use this in your equality:
90! / 10!^9 ≣m x
Calculate each term:
90!m / 10!^9m ≣m x
Then find out your multiplicative inverse from 10!^9m. Then multiplicate the inverse with 90!m.
update
This seems to be correct (at least for this case :)). I checked with wolfram:
(90!/10!^9) mod (10^9+7) = 998551163
This leads to the same result:
90! mod (10^9+7) = 749079870
10!^9 mod (10^9+7) = 220052161
do the inverse:
(220052161 * x) mod(10^9+7) = 1 = 23963055
then:
(749079870*23963055) mod (10^9+7) = 998551163
No proof, but some evidence that it might work :)
I would argue that the way to compute the total number of permutations modulo m, where m is an arbitrary integer (usually chosen to be a large prime number) is to use the following property:
(a * b) % m = ((a % m) * (b % m)) % m
Considering that the total number of permutations of N is N! = 1 * 2 * 3 * .. * N, if you need to compute N! % m, you can essentially apply the property above for multiplication modulo m, and you have:
((((1 * (2 % m)) % m) * (3 % m)) % m) * ..
EDIT
In order to compute the 90! / (10! ^ 9) value you could simplify the factors and then use multiplication modulo m to compute the final result modulo m.
Here's what I'm thinking:
90! = 10! * (11 * 12 * .. * 20) * (21 * 22 * .. * 30) * .. * (81 * 82 * .. * 90)
You can then rewrite the original expression as:
(10! * (11 * 12 * .. * 20) * (21 * 22 * .. * 30) * .. * (81 * 82 * .. * 90)) / (10! * 10! * ... * 10!)
At the numerator, you have a product of 9 factors - considering each expression in parenthesis a factor. The same is true for the denominator (you have 9 factors, each equal to 10!).
The first factor at the denominator is trivial to simplify. After that you still have 8 pairs that need simplification.
So, you can factor each term of the products and simplify the denominator away. For example:
11 * 12 * 13 * 14 * 15 * 16 * 17 * 18 * 19 * 20 <=> 11 * 2 * 2 * 3 * 13 * 2 * 7 * 3 * 5 * 2 * 2 * 2 * 2 * 17 * 2 * 9 * 2 * 2 * 5
The denominator will always be: 2 * 3 * 2 * 2 * 5 * 2 * 3 * 7 * 2 * 2 * 2 * 2 * 3 * 3 * 2 * 5
After the simplification the second pair reduces to : 2 * 2 * 11 * 13 * 17 * 19
The same can be applied to each subsequent pair and you will end up with a simple product that can be computed modulo m using the formula above.
Of course, efficiently implementing the algorithm to perform the simplification will be tricky so ultimately there has to be a better way that eludes me now.

Resources