It's said that floating point addition is commutative but not associative.
An example of it being non associative is the following:
(1 + 1e100) + -1e100 = 0, and 1 + (1e100 + -1e100) = 1
But doesn't this also prove that they are not commutative by the following:
1 + 1e100 + -1e100 = 0, and 1e100 + -1e100 + 1 = 1
Related
I would like to know if it's actually possible to encode a (binary) sequence with rotations in MILP/MIP.
Given a binary sequence (0,1,1,0,0,0,0,1) and variables x0,x1,x2,x3,x4,x5,x6,x7,
I want to restrict my MILP program such that it takes up one of the following:
(x0,x1,x2,x3,x4,x5,x6,x7) = (0,1,1,0,0,0,0,1) or
(x7,x0,x1,x2,x3,x4,x5,x6) = (0,1,1,0,0,0,0,1) or
...
(x1,x2,x3,x4,x5,x6,x7,x0) = (0,1,1,0,0,0,0,1)
I understand that the rotation can be easily solved by just extending the sequence. But I find myself creating multiple MILP instances, each instance corresponding to exactly one of the cases. If this is infeasible, why?
There are many approaches one could design and it's not really clear in what context you will use it.
Here is a relatively simple one:
A: Introduce n new binary variables: These describe the "root / first zero" decision
s_x0, s_x1, s_x2, s_x3, s_x4, s_x5, s_x6, s_x7
B: Add a simplex-constraint / make those add up to 1: We do want a unique root!
s_x0 + s_x1 + s_x2 + s_x3 + s_x4 + s_x5 + s_x6 + s_x7 = 1
C: Encode all implications for all possible roots which can be chosen
for: s_x0
logic-form | milp-form
s_x0 -> x0 (1-s_x0) + x0 >= 1
s_x0 -> x1 (1-s_x0) + x1 >= 1
s_x0 -> !x2 (1-s_x0) + (1-x2) >= 1
s_x0 -> !x3 (1-s_x0) + (1-x3) >= 1
s_x0 -> !x4 (1-s_x0) + (1-x4) >= 1
s_x0 -> !x5 (1-s_x0) + (1-x5) >= 1
s_x0 -> x6 (1-s_x0) + x6 >= 1
s_x0 -> !x7 (1-s_x0) + (1-x7) >= 1
for: s_x1
s_x1 -> !x0 (1-s_x1) + (1-x0) >= 1
s_x1 -> x1 (1-s_x1) + x1 >= 1
s_x1 -> x2 (1-s_x1) + x2 >= 1
s_x1 -> !x3 (1-s_x1) + (1-x3) >= 1
s_x1 -> !x4 (1-s_x1) + (1-x4) >= 1
s_x1 -> !x5 (1-s_x1) + (1-x5) >= 1
s_x1 -> !x6 (1-s_x1) + (1-x6) >= 1
s_x1 -> x7 (1-s_x1) + x7 >= 1
for ......
This:
Basically exploits the core structure behind the problem:
We need to chose between n different patterns and must enforce the effects
Will get big (at least for human-consumption)
Is rather simple / easy to understand and implement
But also should provide a nice LP-relaxation
This (non-compact) formulation also exploits some strengths of MILP-solvers (e.g. clique-tables)
There is a well known problem called "Triple Step" that states:
"A child is running up a staircase with n steps and can hop either 1 step, 2 steps, or 3 steps at a time. Implement a method to count how many possible ways the child can run up the stairs"
The algorithm below is a version without memoization:
int countWays(int n) {
if (n < 0) {
return 0;
} else if (n == 0) {
return 1;
} else {
return countWays(n-1) + countWays(n-2) + countWays(n-3);
}
}
I know that its runtime can be improved from the exponential time complexity.
But I really would like to know how to build a dynamic programming table over this problem,
for example I tried the table below for n being 4 steps:
0 | 1 | 2 | 3 | 4 <= staircase size
1 1 | 1 | 1 | 1 | 1
2 1 | 1 | 2 | 2 | 3
3 1 | 1 | 2 | 3 | 4 <=** There's something wrong because for n=4 the output should be 7
Could someone give me a hint about how this table could be built for the problem above? (or maybe the table is fine and I'm not able to interpret it right)
Thanks!
As you mentioned that countWays(N) can be solved by taking sum of countWays(N-1), countWays(N-2) and countWays(N-3).
Since we know the answer for n<=0, we can start constructing our solution from n=0 to n=N and at any point of time we will always have N-1, N-2 and N-3 values ready to be used.
In the process of constructing solution from n=0 to n=N at any point of time we should have results of our earlier calculations stored somewhere.
you can take 3 variables to store these values and keep updating these 3 variables at each iteration to store the last 3 calculations.
int countWays(int n) {
int last = 1; // for n = 0
int secondLast = 0; // for n = -1
int thridLast = 0; // for n = -2
for(int i = 1 ; i <= n ; i++) {
int current = last + secondLast + thirdLast;
thirdLast = secondLast;
secondLast = last;
last = current;
}
return last;
}
instead of taking 3 variables you can store all the earlier calculations in an array and the code will look like this,
int countWays(int n) {
if(n<0) return 0;
int[] a = new int[n+3];
a[0] = 0;
a[1] = 0;
a[2] = 1; // stores the result for N=0
for(int i = 3 ; i < n+3 ; i++) {
a[i] = a[i-1] + a[i-2] + a[i-3];
}
return a[n+2];
}
and array will look like,
Answer -> [0, 0, 1, 1, 2, 4, 7]
Value Of N -> -2, -1,0 ,1, 2, 3, 4
Array created in this solutions is known is dynamic programming table also known as memoization or bottom up approach to DP
Run time complexity of above solution is O(N)
There is another way to solve these type of problems in O(Log N) time complexity, where solution can be described in terms of a linear recurrence relation.
The solution is known as Matrix Exponentiation, follow this link for more explanation - https://discuss.codechef.com/t/building-up-the-recurrence-matrix-to-compute-recurrences-in-o-logn-time/570
The table for this is 1d which is the staircase size, on every step x you add x-1, x-2, and x-3 if possible, for example:
0 | 1 | 2 | 3 | 4 <= staircase size
1st step 1 | 1 | 0 | 0 | 0 only x-1 is possible
2nd step 1 | 1 | 2 | 0 | 0 x-1 + x-2 are possible
3rd step 1 | 1 | 2 | 4 | 0 x-1 + x-2 + x-3 are possible
4th step 1 | 1 | 2 | 4 | 7 x-1 + x-2 + x-3 are possible
More explanation:
Step 1:
only reachable by 1-step
Step 2:
1-step + 1-step
2-steps
Step 3:
1-step + 1-step + 1-step
1-step + 2-steps
2-steps + 1-step
3-steps
Step 4:
1-step + 1-step + 1-step + 1-step
2-steps + 1-step + 1-step
1-step + 2-steps + 1-step
1-step + 1-step + 2-steps
1-step + 3-steps
3-steps + 1-step
2-steps + 2-steps
Assume that you are using dynamic programming to solve the problem.
Let a be the name of the variable of your table.
The formulae for a[n] with n = 0, 1, 2, .... are as you mentioned:
a[0] = 1
a[n] = a[n-1] + a[n-2] + a[n-3]
Be sure that a[n] for n < 0 is 0 always.
The answer for staircase size = 4 can be solved only if all the answers for 0 <= staircase size < 4 are given. i.e., a[4] can be calculated only if a[0], a[1], ..., a[3] are calculated.
The answer for staircase size = 3 can be solved only if all the answers for 0 <= staircase size < 3 are given. i.e., a[3] can be calculated only if a[0], ..., a[2] are calculated.
The answer for staircase size = 2 can be solved only if all the answers for 0 <= staircase size < 2 are given. i.e., a[2] can be calculated only if a[0], a[1] are calculated.
The answer for staircase size = 1 can be solved only if all the answers for 0 <= staircase size < 1 are given. i.e., a[1] can be calculated only if a[0] is calculated.
a[0] is the first formula.
Here, you can start.
a[0] = 1 // Initialization
a[1] = a[0] + a[-1] + a[-2] = a[0] + 0 + 0 // calculated at 1st loop (a[1] = 1)
a[2] = a[1] + a[0] + a[-1] = a[1] + a[0] + 0 // calculated at 2nd loop (a[2] = 1 + 1)
a[3] = a[2] + a[1] + a[0] // calculated at 3rd loop (a[3] = 2 + 1 + 1)
a[4] = a[3] + a[2] + a[1] // calculated at 4th loop (a[4] = 4 + 2 + 1)
...
a[n] = a[n-1] + a[n-2] + a[n-3] // calculated at nth loop
Perplexed by the function of using a second = sign in vba. eg. s = Int(xVal) + (xVal = n + 1)
I had been deciphering some code and came across the following line which is perplexing me somewhat and despite some extensive research and debugging I seem to be struggling to find the answer:
s = Int(xVal) + (xVal = n + 1)
and
p(i, 3) = A(i)(s + 3 + (s = n)) + (s = n) * (p(i, 1) - p(i, 2))
My question is what is the function of the comparisons within the parentheses after the first assignment = sign?
TIA
(s = n)
If both s and n have the same value then this evaluates to True, which can be coerced to its underlying value of -1 by other arithmetic operations.
Eg:
? True * 1 '>> -1
? False * 1 '>> 0
So this:
s = Int(xVal) + (xVal = n + 1)
is like writing:
If xVal = n + 1 Then
s = Int(xVal) + -1
else
s = Int(xVal) + 0
end if
or:
s = Int(xVal) + IIf(xVal = n + 1, -1, 0)
My problem is simple.
I am searching a mathematical function to distribute number over an interval.
For example I have this list :
[2; 4; 9; 14]
And in my case I wish
2 -> 1 = f(2)
14 -> 20 = f(14)
4 -> f(4) = ?
9 -> f(9) = ?
This is just an example I am searching for f(x).
Someone would have any idea ?
Thanks for advance ! :)
If you want a linear function, then:
f(x) = lowerFunc + (x - lowerX) * (upperFunc - lowerFunc) / (upperX - lowerX),
where:
lowerFunc: function value at the lower end
upperFunc: function value at the upper end
lowerX: x parameter at the lower end
upperX: x parameter at the upper end.
For your example:
f(x) = 1 + (x - 2) * (20 - 1) / (14 - 2)
= 1 + (x - 2) * 19/12
f(2) = 1
f(4) = 4.1666
f(9) = 12.08333
f(14) = 20
I've had a look at similar questions that have been asked, and have asked my classmates for advice but I am questioning the answer.
What's the time complexity of this algorithm?
for (i = 1; i < n; i *= 2)
for (j = 1; j < i; j *= 2)
\\ c elementary operations
I have been told O(log(n))^2 but from what I've read and tried it looks like O(log(n)*log(log(n))). Any help?
The inner loops repeats itself log_2(i) times for each iteration of the outer loop.
Let's sum that up then
(1) T(n) = log_2(1) + log_2(2) + log_2(4) + log_2(8) + ... + log_2(n)
(2) T(n) = sum { log_2(2^i) | i=0,1,..,log_2(n) }
(3) T(n) = sum { i * log_2(2) | i=0,1,...,log_2(n) }
(4) T(n) = 0 + 1 + ... + log_2(n)
(5) T(n) = (log_2(n) + 1)(log_2(n))/2
(6) T(n) is in O(log_2(n)^2)
Explanation:
(1) -> (2) is simply summation shorthand
(2) -> (3) is because log(a^b) = blog(a)
(3) -> (4) log_2(2) = 1
(4) -> (5) Sum of arithmetic progression
(5) -> (6) is giving asymptotic notation