Algorithm Recurrence formula - algorithm

I am reading Algorithms in C++ by Robert Sedgewick. Basic recurrences section it was mentioned as This recurrence arises for a recursive program that loops through the input to eliminate one item
Cn = cn-1 + N, for N >=2 with C1 = 1.
Cn is about Nsquare/2. Evaluating the sum 1 + 2 +...+ N is elementary. in addition to this following statement is mentioned.
" This result - twice the value sought - consists of N terms, each of which sums to N +1
I need help in understanding abouve statement what are N terms here and how each sums to
N +1, aslo what does "twice the value sought" means.
Thanks for your help

I think he refers to this basic mathematical trick to calculate that sum. Although, it's difficult to conclude anything from such short passage you cited.
Let's assume N = 100. E.g., the sum is 1 + 2 + 3 + .. + 99 + 100.
Now, let's group pairs of elements with sum 101: 1 + 100, 2 + 99, 3 + 98, ..., 50 + 51. That gives us 50 (N/2) pairs with sum 101 (N + 1) in each: thus the overall sum is 50*101.
Anyway, could you provide a bit more context to that quote?

The recurrence formula means:
C1 = 1
C2 = C1 + 2 = 1 + 2 = 3
C3 = C2 + 3 = 3 + 3 = 6
C4 = C3 + 4 = 6 + 4 = 10
C5 = C4 + 5 = 10 + 5 = 15
etc.
But you can also write it directly:
C5 = 1 + 2 + 3 + 4 + 5 = 15
And then use the old trick:
1 + 2 + 3 + ... + N
+ N + N-1 + N-2 + ... + 1
-------------------------
(N+1) ... (N+1)
= (N+1) * N
From there we get : 1 + 2 + ... N = N * (N+1) / 2
For the anecdote, the above formula was found by the great mathematician Carl Friedrich Gauss, when he was at school.
From there we can deduce a recursive algorithm is O(N square) and that is probably what Robert Sedgewick is doing.

Related

Summation of series 1 + (1+2+1) + (1+2+1+3+1+2+1)

The function is : F(n-1) n F(n-1)
Its a type of palindrome function called Zimmer Series.
The values would be : 1, 121, 1213121, ...
I want to figure the summation of the individual digits.
1 + (1+2+1) + (1+2+1+3+1+2+1) + ...
Any help is welcome.
Breaking this down into steps, we first find out a formula for the summation of a single value of the series and then we can find out the summation of said formula.
Expanding the definition you gave and manipulating it:
F(n) = n + 2F(n-1)
F(n) = n + 2(n-1) + 22(n-2) + 23(n-3) + ... + 2n-1
2F(n) = 2n + 22(n-1) + 23(n-2) + ... + 2n-1(2) + 2n
F(n) - 2F(n) = -F(n) = n - 2 - 22 - 23 - ... - 2n
From this and using the formula for Geometric Progression we can then get an expression for a single term of the series.
F(n) = (2n + 2n-1 + ... + 2) - n
= (2n+1 - 2) - n
Now we just have to work out the summation of this expression.
G(n) = Σ F(n) = Σ (2n+1 - 2 - n)
G(n) = (2n+2 - 22) - (2n) - (n(n+1)/2)
Simplifying this should hopefully give you the answer you seek!
G(n) = (2n+2 - (n(n+5)/2) - 22)
Trying this out on a few of the terms just to double check.
G(1) = (21+2 - (1(1+5)/2) - 22)
G(1) = 1
G(2) = (22+2 - (2(2+5)/2) - 22)
G(2) = 5 = 1 + (1 + 2 + 1)
G(3) = (23+2 - (3(3+5)/2) - 22)
G(3) = 16 = 1 + (1 + 2 + 1) + (1 + 2 + 1 + 3 + 1 + 2 + 1)
EDIT: Mark Dickinson is right, I misinterpreted the question, this solution is incorrect.
I think after the second term the sequence is of the form difference in Arithmetic Progression.
Let me show you how
Second Term = 1+2+1
Third Term = 1+2+1+3 + 1+2+1
Difference = 1+2+1+3 = 7
Third Term = 1+2+1+3+1+2+1
Fourth Term = 1+2+1+3+ 1+4+1+3 +1+2+1
Difference = 1+4+1+3 = 9
Fourth Term = 1+2+1+3+1+4+1+3+1+2+1
Fifth Term = 1+2+1+3+1+4+ 1+5+1+4 +1+3+1+2+1
Difference = 1+5+1+4 = 11
So as you can see the difference is in the arithmetic progression and you find the sum of the terms using the formula for the sum of numbers whose different are in Arithmetic Progression

How do I derive the Bubble Sort Comparison Formula?

So I'm in high school learning about sorting algorithms, and we've analyzed Bubble Sort recently.
My teacher showed the formula to find the number of comparisons (C) it takes Bubble Sort to sort a certain number of items (n)
So the equation is:
C = (n-1) + (n-2) + (n-3) + ... + 3 + 2 + 1
= [n(n-1)]/2
The only thing I'm a little confused about is how you derive:
C = [n(n-1)]/2
from
C = (n-1) + (n-2) + (n-3) + ... + 3 + 2 + 1
I know this is most likely pretty basic math, but I just can't figure it out. I've searched online but they don't really show a step-by-step of how exactly to do it.
There are (at least) three ways to approach it.
By staring at it until you see the pattern:
n C
1 0
2 1
3 3
4 6
5 10
. .
. .
. .
Geometrically, by seeing that it's half of a rectangle:
*****
****
***
**
*
Algebraically, by rearranging elements:
C = (n-1) + (n-2) + (n-3) + ... + 3 + 2 + 1
= [(n-1)+1] + [(n-2)+2] + [(n-3)+3] + ...
= n + n + n + ...
(You can also prove it by induction, after you discover it by some other means.)
Its just the sum upto n elements in Arithmetic Progression with a difference of 1, given by : n*(n+1)/2. So from 1 to n-1 elements you have (n-1)*(n-1+1)/2 = n(n-1)/2.
Look up : https://en.wikipedia.org/wiki/Arithmetic_progression for the general formula of an Arithmetic Progression.
Another way to solve this:
S = 1 + 2 + .... + (n-1) ... [Eq 1]
Writing backwards:
S = (n-1) + (n-2) + ... +2 + 1 ....[Eq 2]
Adding Eq (1) and (2) we have:
2S = n + n .... upto (n-1) terms
Finally:
S = [n*(n-1)]/2

Determine the computational complexity of the following algorithm

s = 0
for i = 1 to n3
for j = 1 to i do
s = s + 1
what is mean by computational complexity?
Let's assume each operation i in this code takes constant time ci. Then the running time can be expressed by the sum c1 + c2 * n3 + c3 * i * n3 + c4 * i * n3. We consider constant coefficients as insignificant because they only contribute a constant value regardless of the input. This gives us Θ(1) + Θ(n3) + Θ(i * n3 + 1) + Θ(i * n3). So in this case the time complexity is Θ(n3!) which is to say this algorithm runs in factorial time.
Just calculate some values (how many times s = s + 1 is executed for each iteration of i and sum up) and see what you get:
1 + 2 + 3 + ... + n = n * (n + 1) / 2 = n^2 / 2 + n / 2 => complexity O(n^2).

Calculating 1^X + 2^X + ... + N^X mod 1000000007

Is there any algorithm to calculate (1^x + 2^x + 3^x + ... + n^x) mod 1000000007?
Note: a^b is the b-th power of a.
The constraints are 1 <= n <= 10^16, 1 <= x <= 1000. So the value of N is very large.
I can only solve for O(m log m) if m = 1000000007. It is very slow because the time limit is 2 secs.
Do you have any efficient algorithm?
There was a comment that it might be duplicate of this question, but it is definitely different.
You can sum up the series
1**X + 2**X + ... + N**X
with the help of Faulhaber's formula and you'll get a polynomial with an X + 1 power to compute for arbitrary N.
If you don't want to compute Bernoulli Numbers, you can find the the polynomial by solving X + 2 linear equations (for N = 1, N = 2, N = 3, ..., N = X + 2) which is a slower method but easier to implement.
Let's have an example for X = 2. In this case we have an X + 1 = 3 order polynomial:
A*N**3 + B*N**2 + C*N + D
The linear equations are
A + B + C + D = 1 = 1
A*8 + B*4 + C*2 + D = 1 + 4 = 5
A*27 + B*9 + C*3 + D = 1 + 4 + 9 = 14
A*64 + B*16 + C*4 + D = 1 + 4 + 9 + 16 = 30
Having solved the equations we'll get
A = 1/3
B = 1/2
C = 1/6
D = 0
The final formula is
1**2 + 2**2 + ... + N**2 == N**3 / 3 + N**2 / 2 + N / 6
Now, all you have to do is to put an arbitrary large N into the formula. So far the algorithm has O(X**2) complexity (since it doesn't depend on N).
There are a few ways of speeding up modular exponentiation. From here on, I will use ** to denote "exponentiate" and % to denote "modulus".
First a few observations. It is always the case that (a * b) % m is ((a % m) * (b % m)) % m. It is also always the case that a ** n is the same as (a ** floor(n / 2)) * (a ** (n - floor(n/2)). This means that for an exponent <= 1000, we can always complete the exponentiation in at most 20 multiplications (and 21 mods).
We can also skip quite a few calculations, since (a ** b) % m is the same as ((a % m) ** b) % m and if m is significantly lower than n, we simply have multiple repeating sums, with a "tail" of a partial repeat.
I think Vatine’s answer is probably the way to go, but I already typed
this up and it may be useful, for this or for someone else’s similar
problem.
I don’t have time this morning for a detailed answer, but consider this.
1^2 + 2^2 + 3^2 + ... + n^2 would take O(n) steps to compute directly.
However, it’s equivalent to (n(n+1)(2n+1)/6), which can be computed in
O(1) time. A similar equivalence exists for any higher integral power
x.
There may be a general solution to such problems; I don’t know of one,
and Wolfram Alpha doesn’t seem to know of one either. However, in
general the equivalent expression is of degree x+1, and can be worked
out by computing some sample values and solving a set of linear
equations for the coefficients.
However, this would be difficult for large x, such as 1000 as in your
problem, and probably could not be done within 2 seconds.
Perhaps someone who knows more math than I do can turn this into a
workable solution?
Edit: Whoops, I see Fabian Pijcke had already posted a useful link about Faulhaber's formula before I posted.
If you want something easy to implement and fast, try this:
Function Sum(x: Number, n: Integer) -> Number
P := PolySum(:x, n)
return P(x)
End
Function PolySum(x: Variable, n: Integer) -> Polynomial
C := Sum-Coefficients(n)
P := 0
For i from 1 to n + 1
P += C[i] * x^i
End
return P
End
Function Sum-Coefficients(n: Integer) -> Vector of Rationals
A := Create-Matrix(n)
R := Reduced-Row-Echelon-Form(A)
return last column of R
End
Function Create-Matrix(n: Integer) -> Matrix of Integers
A := New (n + 1) x (n + 2) Matrix of Integers
Fill A with 0s
Fill first row of A with 1s
For i from 2 to n + 1
For j from i to n + 1
A[i, j] := A[i-1, j] * (j - i + 2)
End
A[i, n+2] := A[i, n]
End
A[n+1, n+2] := A[n, n+2]
return A
End
Explanation
Our goal is to obtain a polynomial Q such that Q(x) = sum i^n for i from 1 to x. Knowing that Q(x) = Q(x - 1) + x^n => Q(x) - Q(x - 1) = x^n, we can then make a system of equations like so:
d^0/dx^0( Q(x) - Q(x - 1) ) = d^0/dx^0( x^n )
d^1/dx^1( Q(x) - Q(x - 1) ) = d^1/dx^1( x^n )
d^2/dx^2( Q(x) - Q(x - 1) ) = d^2/dx^2( x^n )
... .
d^n/dx^n( Q(x) - Q(x - 1) ) = d^n/dx^n( x^n )
Assuming that Q(x) = a_1*x + a_2*x^2 + ... + a_(n+1)*x^(n+1), we will then have n+1 linear equations with unknowns a1, ..., a_(n+1), and it turns out the coefficient cj multiplying the unknown aj in equation i follows the pattern (where (k)_p = (k!)/(k - p)!):
if j < i, cj = 0
otherwise, cj = (j)_(i - 1)
and the independent value of the ith equation is (n)_(i - 1). Explaining why gets a bit messy, but you can check the proof here.
The above algorithm is equivalent to solving this system of linear equations.
Plenty of implementations and further explanations can be found in https://github.com/fcard/PolySum. The main drawback of this algorithm is that it consumes a lot of memory, even my most memory efficient version uses almost 1gb for n=3000. But it's faster than both SymPy and Mathematica, so I assume it's okay. Compare to Schultz's method, which uses an alternate set of equations.
Examples
It's easy to apply this method by hand for small n. The matrix for n=1 is
| (1)_0 (2)_0 (1)_0 | | 1 1 1 |
| 0 (2)_1 (1)_1 | = | 0 2 1 |
Applying a Gauss-Jordan elimination we then obtain
| 1 0 1/2 |
| 0 1 1/2 |
Result = {a1 = 1/2, a2 = 1/2} => Q(x) = x/2 + (x^2)/2
Note the matrix is always already in row echelon form, we just need to reduce it.
For n=2:
| (1)_0 (2)_0 (3)_0 (2)_0 | | 1 1 1 1 |
| 0 (2)_1 (3)_1 (2)_1 | = | 0 2 3 2 |
| 0 0 (3)_2 (2)_2 | | 0 0 6 2 |
Applying a Gauss-Jordan elimination we then obtain
| 1 1 0 2/3 | | 1 0 0 1/6 |
| 0 2 0 1 | => | 0 1 0 1/2 |
| 0 0 1 1/3 | | 0 0 1 1/3 |
Result = {a1 = 1/6, a2 = 1/2, a3 = 1/3} => Q(x) = x/6 + (x^2)/2 + (x^3)/3
The key to the algorithm's speed is that it doesn't calculate a factorial for every element of the matrix, instead it knows that (k)_p = (k)_(p-1) * (k - (p - 1)), therefore A[i,j] = (j)_(i-1) = (j)_(i-2) * (j - (i - 2)) = A[i-1, j] * (j - (i - 2)), so it uses the previous row to calculate the current one.

Skiena the Algorithm Design Manual - Geometric Series Clarification

Picture taken from book.
That is an explanation of a geometric series from the book, which I do not understand.
Constant ratio is a right?
So let's take first term (just the sum function), for n = 5, and constant ratio = 2.
So we will have this:
2^0 + 2^1 + 2^2 + 2^3 + 2^4 + 2^5 = 1 + 2 + 4 + 8 + 16 + 32 = 63
No if I use the RHS,
a(a^n+1 - 1)/(a - 1).
So it will give this: 2(2^5+1 - 1)/(2 - 1) for n = 5 this gives 126.
How can they be equal ?
Also it says later on: 'when a > 1 the sum grows rapidly with each new term..' Is he talking about space complexity ?
Because I do not get the big-theta notation. So for n = 5 and a = 2 it will take Big-Theta(64), 64 (2^6) steps?
Here is some ruby code:
n = 5
a = 2
sum = 0
for i in 0..n do
sum = sum + a**i
end
puts sum # prints 63
I can see n+1 steps.
Any help understanding this please?
The formula in the book is wrong, there is an extra a factor (n=0 should yield 1, not a).
"The sum grows rapidly" is just about the values of the sum, it does not describe the complexity of computing it.

Resources