Exponential backoff - math

Let's say I had the equation T = sum(A**n) for n from 1 to M.
Now let's say I knew M and T, but wanted A. How would I solve for A?
I want to do an exponential backoff in the event of an error, but I don't want the total time spent backing off to be greater than T, nor the maximum number of retries to exceed M. So I'd need to find A.

The closed-form solution for sum(A**n) for n from 1 to M is (A^(M+1) - 1) / (A - 1) - 1. To see this work, let M = 3 and A = 2. Then 2^1 + 2^2 + 2^3 = 14, and (2^4 - 1) / (2 - 1) - 1 = 15 / 1 - 1 = 14.
So, we have the closed form expression T = (A ^ (M + 1) - 1) / (A - 1) - 1. This is a transcendental equation and has no closed-form solution. However, because the RHS is monotonically increasing in A (bigger values of A always give bigger values of the expression) then we can do what amounts to binary search to find an answer to arbitrary precision:
L = 0
H = MAX(T, 2)
A = (L + H) / 2
while |(A ^ (M + 1) - 1) / (A - 1) - 1 - T| > precision
if (A ^ (M + 1) - 1) / (A - 1) - 1 > T then
H = A
else then
L = A
end if
A = (L + H) / 2
loop
Example: T = 14, M = 3, epsilon = 0.25
L = 0
H = MAX(15, 2) = 14
A = L + H / 2 = 7
|(A ^ (M + 1) - 1) / (A - 1) - 1 - T|
= 385 > 0.25
H = A = 7
A = (L + H) / 2 = 3.5
|(A ^ (M + 1) - 1) / (A - 1) - 1 - T|
= 44.625 > 0.25
H = A = 3.5
A = (L + H) / 2 = 1.75
|(A ^ (M + 1) - 1) / (A - 1) - 1 - T|
= 3.828125 > 0.25
L = A = 1.75
A = (L + H) / 2 = 2.625
|(A ^ (M + 1) - 1) / (A - 1) - 1 - T|
= 13.603515625 > 0.25
H = A = 2.625
A = (L + H) / 2 = 2.1875
|(A ^ (M + 1) - 1) / (A - 1) - 1 - T|
= 3.440185546875 > 0.25
H = A = 2.1875
A = (L + H) / 2 = 1.96875
|(A ^ (M + 1) - 1) / (A - 1) - 1 - T|
= 0.524444580078125 > 0.25
L = A = 1.96875
A = (L + H) / 2 = 2.078125
|(A ^ (M + 1) - 1) / (A - 1) - 1 - T|
= 1.371326446533203125 > 0.25
H = A = 2.078125
A = (L + H) / 2 = 2.0234375
|(A ^ (M + 1) - 1) / (A - 1) - 1 - T|
= 0.402295589447021484375 > 0.25
H = A = 2.0234375
A = (L + H) / 2 = 1.99609375
|(A ^ (M + 1) - 1) / (A - 1) - 1 - T|
= 0.066299498081207275390625 < 0.25
Solution: 1.99609375

Related

Why is this Recurrence Relation O(1)?

Rewrote the solved question below for a reference:
Original question:
T(n) = 2T(n - 1) - 1, if n > 0
1, otherwise
1st iteration
T(n) = 2T(n - 1) - 1
T(n - 1) = 2T(n - 1 - 1) - 1
T(n - 1) = 2T(n - 2) - 1
2nd iteration
T(n) = 2(2T(n - 2) - 1) - 1
T(n) = 4T(n - 2) - 2 - 1
T(n) = 4T(n - 2) - 3
T(n - 2) = 2T(n - 2 - 1) - 1
T(n - 2) = 2T(n - 3) - 1
3rd iteration
T(n) = 4(2T(n - 3) - 1) - 3
T(n) = 8T(n - 3) - 4 - 3
T(n) = 8T(n - 3) - 7
T(n - 3) = 2T(n - 3 - 1) - 1
T(n - 3) = 2T(n - 4) - 1
4th iteration
T(n) = 8T(n - 3) - 7
T(n) = 8(2T(n - 4) - 1) - 7
T(n) = 16T(n - 4) - 8 - 7
T(n) = 16T(n - 4) - 15
Final table
At k=1, T(n) = 2T(n - 1) - 1
At k=2, T(n) = 4T(n - 2) - 3
At k=3, T(n) = 8T(n - 3) - 7
At k=4, T(n) = 16T(n - 4) - 15
T(n) = 2ᴷT(n - k) - (2ᴷ - 1)
At k=n T(n) = 2ᴺT(n - n) - (2ᴺ - 1)
T(n) = 2ᴺT(0) - (2ᴺ - 1)
T(n) = 2ᴺ - (2ᴺ - 1)
T(n) = 2ᴺ - 2ᴺ + 1
T(n) = 1
The inductive proof that T(n) = 1 looks like this:
Induction start.
What is T(0)? 1.
Induction step.
Assume for any n >= 0 that T(n) = 1. Now let's see if the claim holds for T(n+1).
T(n+1) = 2*T(n) - 1 = 2*1 - 1 = 1
Conclusion.
T(n) = 1 for all natural n. And 1 is in O(1).
Your error.
The first error I found in your calculation is here:
T(n) = 2²(2T(n - 3) - 1) - 3
T(n) = 2³T(n - 3) - 2 - 3
^ this should be a 4
T(n) = 2T(n-1) -1
= 2(2T(n-2)-1) - 1 = 4T(n-2)-3 = (2^2)T(n-2)-(2^2-1)
= 2(4T(n-3)-3) - 1 = 8T(n-3)-7 = (2^3)T(n-3)-(2^3-1)
...
= (2^n)T(n-n)-(2^n-1) = (2^n)1 - 2^n + 1 = 1

Finding a Closed Form for Recursive Function [closed]

Closed. This question is not reproducible or was caused by typos. It is not currently accepting answers.
This question was caused by a typo or a problem that can no longer be reproduced. While similar questions may be on-topic here, this one was resolved in a way less likely to help future readers.
Closed 6 years ago.
Improve this question
Consider the following recurrence relation.
T(n) = 5 if n <= 2
T(n-1) + n otherwise
Closed form solution for T(n) is
I got solution as n(n+1)/2 + 7 for all the values. But in my university exam they gave the solution n(n+1)/2 + 2. However this solution doesn't terminate at 5 for values n<2. Can some body please explain ?
Let's solve it; first let's expand in telescopic sums:
T(k) = T(k)
T(k + 1) = T(k) + k + 1
T(k + 2) = T(k + 1) + k + 2 = T(k) + k + 1 + k + 2
...
T(k + m) = T(k) + k + 1 + k + 2 + ... + k + m =
= T(k) + mk + 1 + 2 + ... + m =
= T(k) + mk + (1 + m) * m / 2
...
Now we have
T(k + m) = T(k) + mk + (1 + m) * m / 2
Let k = 2:
T(m + 2) = T(2) + 2m + (1 + m) * m / 2 = 5 + 2m + (1 + m) * m / 2
Finally, let m + 2 = n or m = n - 2:
T(n) = 5 + 2 * (n - 2) + (n - 1) * (n - 2) / 2 = n * (n + 1) / 2 + 2
We have
T(n) = n * (n + 1) / 2 + 2 when n > 2
T(n) = 5 when n <= 2
As a simple non-rigorous reasoning exercise, we known that T(n) = T(n-1) + n yields the sum of the first n numbers: S(n) = n * (n + 1) / 2
Now, when n=2, S(2) = 3, so the value of 5 is actually an increment by 5 - S(2) = 2. So we could say:
T(n) = S(n) + (5 - S(2)) for n >=2
or
T(n) = S(n) + 2 for n >= 2
T(n) = 5 for n <= 2
Note that at n=2, the two relations are identical.

How to algebraically solve a system of equations?

I am not sure whether this is right place to ask. Here N, L, H, p, and d are parameters. I need to solve this system of equations. Specifically, I need to solve for b(t) and e(t).
Variables | t=1 | t>1
----------|--------|------------------------
n(t) | N |N(1-p)^(t-1)
s(t) | 1 |((1-p+dp)/(1-p))^(t-1)
b(t) | L |b(t-1)+p(H-b(t-1))
e(t) |(H-L)/2 |e(t-1)+(p(H-b(t-1)))/2
c(t) |(1-d)pN |(1-d)pN(1-p+dp)^(t-1)
Please help me how should I start this problem to solve.
Since you used a Wolfram-Mathematica tag, perhaps you intend to use Mathematica
RSolve[{b[1]==L, b[t]==b[t-1]+p(H-b[t-1]),
e[1]==(H-L)/2, e[t]==e[t-1]+p(H-b[t-1])/2}, {b[t],e[t]}, t]//FullSimplify
which returns
Solve::svars: Equations may not give solutions for all "solve" variables
{b[t]->H+(-H+L)(1-p)^(-1+t),
e[t]->((H-L)(-2+(1-p)^t+2 p))/(2(-1+p))}
It seems that these formulas give recurrent equations - you find values for t = 1 (from table), then calculate values for t = 2, then for t = 3 and so on
b(t) = b(t-1) + p * (H - b(t-1))
t = 1: L
t = 2: b(2) = b(1) + p * (H - b(1)) or
L + p * (H - L) = L + p * H - p * L
t = 3: b(3) = b(2) + p * (H - b(2))
Example: L= 2; p = 3; H = 7;
b(1) = 2
b(2) = 2 + 3 * (7 - 2) = 17
b(3) = 17 + 3 * (7 - 17) = -13

Non Decreasing Number Combinations (Interval)

So my problem is the following:
Given a number X of size and an A (1st number), B(Last number) interval, I have to find the number of all different kind of non decreasing combinations (increasing or null combinations) that I can build.
Example:
Input: "2 9 11"
X = 2 | A = 9 | B = 11
Output: 8
Possible Combinations ->
[9],[9,9],[9,10],[9,11],[10,10],[10,11],[11,11],[10],[11].
Now, If it was the same input, but with a different X, line X = 4, this would change a lot...
[9],[9,9],[9,9,9],[9,9,9,9],[9,9,9,10],[9,9,9,11],[9,9,10,10]...
Your problem can be reformulated to simplify to just two parameters
X and N = B - A + 1 to give you sequences starting with 0 instead of A.
If you wanted exactly X numbers in each item, it is simple combination with repetition and the equation for that would be
x_of_n = (N + X - 1)! / ((N - 1)! * X!)
so for your first example it would be
X = 2
N = 11 - 9 + 1 = 3
x_of_n = 4! / (2! * 2!) = 4*3*2 / 2*2 = 6
to this you need to add the same with X = 1 to get x_of_n = 3, so you get the required total 9.
I am not aware of simple equation for the required output, but when you expand all the equations to one sum, there is a nice recursive sequence, where you compute next (N,X) from (N,X-1) and sum all the elements:
S[0] = N
S[1] = S[0] * (N + 1) / 2
S[2] = S[1] * (N + 2) / 3
...
S[X-1] = S[X-2] * (N + X - 1) / X
so for the second example you give we have
X = 4, N = 3
S[0] = 3
S[1] = 3 * 4 / 2 = 6
S[2] = 6 * 5 / 3 = 10
S[3] = 10 * 6 / 4 = 15
output = sum(S) = 3 + 6 + 10 + 15 = 34
so you can try the code here:
function count(x, a, b) {
var i,
n = b - a + 1,
s = 1,
total = 0;
for (i = 0; i < x; i += 1) {
s *= (n + i) / (i + 1); // beware rounding!
total += s;
}
return total;
}
console.log(count(2, 9, 11)); // 9
console.log(count(4, 9, 11)); // 34
Update: If you use a language with int types (JS has only double),
you need to use s = s * (n + i) / (i + 1) instead of *= operator to avoid temporary fractional number and subsequent rounding problems.
Update 2: For a more functional version, you can use a recursive definition
function count(x, n) {
return n < 1 || x < 1 ? 0 : 1 + count(n - 1, x) + count(n, x - 1);
}
where n = b - a + 1

Solving the recurrence W(n) = W(n / 2) + n log n?

Please verify my logic to see if what I'm attempting is valid or shady.
W(n) = W(n/2) + nlg(n)
W(1) = 1
n =2^k
By trying the pattern
line 1 : W (2^k) = W(2^k-1) + nlgn
line 2 : = W(2^k-2) + nlgn + nlgn
...
line i : = W(2^k-i) + i*nlgn
and then solve the rest for i.
I just want to make sure it's cool if I substitute in 2k in one place (on line 1) but not in the other for the n lg n.
I find by subbing in 2^k for 2^k lg(2^k) gets really greasy.
Any thoughts are welcome (specifically if I should be subbing in 2^k, and if I should then how would you suggest the solution)
It's fine to switch back and forth between n and 2k as needed because you're assuming that n = 2k. However, that doesn't mean that what you have above is correct. Remember that as n decreases, the value of n log n keeps decreasing as well, so it isn't the case that the statement
line i = W(2k-i) + i * n lg n
is true.
Let's use the iteration method one more time:
W(n) = W(n / 2) + n log n
= (W(n / 4) + (n/2) log (n/2)) + n log n
= W(n / 4) + (n/2) (log n - 1) + n log n
= W(n / 4) + n log n / 2 - n / 2 + n log n
= W(n / 4) + (1 + 1/2) n log n - n / 2
= (W(n / 8) + (n / 4) log(n/4)) + (1 + 1/2) n log n - n / 2
= W(n / 8) + (n / 4) (log n - 2) + (1 + 1/2) n log n - n / 2
= W(n / 8) + n log n / 4 - n / 2 + (1 + 1/2) log n - n / 2
= W(n / 8) + (1 + 1/2 + 1/4) n log n - n
= (W(n / 16) + (n / 8) log(n/8)) + (1 + 1/2 + 1/4) n log n - n
= W(n / 16) + (n / 8) (log n - 3)) + (1 + 1/2 + 1/4) n log n - n
= W(n / 16) + n log n / 8 - 3n / 8 + (1 + 1/2 + 1/4) n log n - n
= W(n / 16) + (1 + 1/2 + 1/4 + 1/8) n log n - n - 3/8n
We can look at this to see if we spot a pattern. First, notice that the n log n term has a coefficient of (1 + 1/2 + 1/4 + 1/8 + ...) as we keep expanding outward. This series converges to 2, so when the iteration stops that term will be between n log n and 2n log n. Next, look at the coefficient of the -n term. If you look closely, you'll notice that this coefficient is -1 times
(1 / 2 + 2 / 4 + 3 / 8 + 4 / 16 + 5 / 32 + ... )
This is the sum of i / 2i, which converges to 2. Therefore, if we iterate this process, we'll find at each step that the value is Θ(n log n) - Θ(n), so the overall recurrence solves to Θ(n log n).
Hope this helps!

Resources