/*#
requires 0 <= lb < N_LOG_BLOCKS && 0 <= lp < N_PAGE ;
requires ( 1 <= h_clean_counter + l_clean_counter <= N_PHY_BLOCKS );
requires 0 <= h_act_block_index_p < N_PHY_BLOCKS && 0 <= h_act_page_p < N_PAGE;
requires 0 <= l_act_block_index_p < N_PHY_BLOCKS && 0 <= l_act_page_p < N_PAGE;
requires 0 <= l_to_p[lb][lp] < N_PHY_BLOCKS * N_PAGE || l_to_p[lb][lp] == -1;
requires -2147483648 <= d <= 2147283647 ;
requires 0 <= chance_index_p < LRU_SIZE;
requires 0 <= index_2_physical[h_act_block_index_p] < N_PHY_BLOCKS ;
requires \forall integer i; 0 <= i < N_PHY_BLOCKS ==> 0 <= index_2_physical[i] < N_PHY_BLOCKS;
requires 0 <= l_array_counter < N_PHY_BLOCKS/2;
requires l_clean_counter == low_array_counter;
requires h_clean_counter == high_array_counter;
...
*/
My code has tons of variables with some intended bound. As a result, I need to put all these bound constraints in all "requires" and "ensures" regions of all functions. I wonder whether there is a smarter way for me to specify the variable bound, preferably in a global manner.
If these bounds are indeed the same for all functions and you have global variables or the formals are consistently named across all functions, I'd say that this is something MetAcsl can do for you, with something like (for your first requires)
/*# meta \prop,
\name(lb_bounds),
\context(\precond),
\targets(\ALL),
0 <= lb < N_LOG_BLOCKS;
*/
[NB: I haven't tried to type-check it, it may contain typos]
Basically, this tells MetAcsl to insert a pre-condition (because of the \precond context) to \ALL functions saying 0<= lb < N_LOG_BLOCKS.
You can find more information about the annotations that can be generated by MetAcsl on its gitlab repository.
Related
I am struggling with some constraints that have ranged variables and several decision variables.
The constraints are
`if a[i] <= t <= a[i]+b[i], then M[t][i] == 1,
else if t < a[i] or t > a[i]+b[i], then M[t][i] == 0.
decision variables (int a[i], b[i])
(boolean M[t][i])
Examples of ranges of the variables
0 <= a[i] <= 50
0 <= b[i] <= 10
0 <= t <= 100`
I'd like to linearize these formulations, like as Big-M method or etc...
Plz, let me know the way to overcome it.
Thank you.
Linearization by using the Big-M method or etc...
such as...
M*t + (M-1)*t <= M*(a[i]) + (M-1)*a[i]
it works with
x[x >= 0.2] = 1
x[x < 0.2] = 0
x is a tensor here.
but when i am trying to use
x[x > 0 and x < 1] = 1
it reports: RuntimeError: bool value of Tensor with more than one value is ambiguous ?
dose anyone know why?
Just a syntax thing.
x = torch.randn((1,3,20,20))
x[(x > 0) & (x < 1)] = 1
I am trying to create a linear optimization model. I have a set that looks like this:
si=[1,51,39,400909,1244]
sj=[31,47,5]
The numbers in this set represent codes. I am trying to loop through the set to add a constraint to my model, but I do not want to loop through the sets using their values, I want to loop through the sets based on their indices.
Here is the code I have now:
si=[1,51,39,400909,1244]
sj=[31,47,5]
c= [3 5 2;
4 3 5;
4 5 3;
5 4 3;
3 5 4]
b= [80;
75;
80;
120;
60]
# x_ij >= 0 ∀ i = 1,...,5, j = 1,...,3
#defVar(m, x[i in si,j in sj] >= 0)
#setObjective(m,Min,sum{c[i,j]*x[i,j],i in si, j in sj})
# ∀j = 1,...,3
for j in sj
#addConstraint(m, sum{x[i,j],i in si} <= 480)
end
for i in si
#addConstraint(m, sum{x[i,j],j in sj} >= b[i])
end
I keep getting an error because the numbers in the sets are too big. Does anyone know how to loop through the indices instead? Or does anyone have another way to do this?
I am also having trouble printing my solution. Here is my code:
for i in n
for j in p
println("x",i,",",j,"= ", getValue(x[i,j]))
end
end (incorporating Iain Dunning's answer from below)
However the output only reads
Objective value: 1165.0
x5,3= 0.0
Do you know how to fix the output so I can read the values of my variables?
The code you have posted doesn't work because you are trying to index c by, e.g. 400909,47. Try this:
n = length(si)
p = length(sj)
#variable(m, x[i=1:n,j=1:p] >= 0)
#objective(m,Min,sum{c[i,j]*x[i,j],i=1:n,j=1:p})
for j in 1:p
#constraint(m, sum{x[i,j],i=1:n} <= 480)
end
for i in 1:n
#constraint(m, sum{x[i,j],j=1:p} >= b[i])
end
I want to understand how the modulus operator works when applied to two intervals. Adding, subtracting and multiplying two intervals is trivial to implement in code, but how do you do it for modulus?
I'd be happy if someone can show me the formula, sample code or a link which explains how it works.
Background info: You have two integers x_lo < x < x_hi and y_lo < y < y_hi. What is the the lower and upper bound for mod(x, y)?
Edit: I'm unsure if it is possible to come up with the minimal bounds in an efficient manner (without calculating the mod for all x or for all y). If so, then I'll accept an accurate but non-optimal answer for the bounds. Obviously, [-inf,+inf] is a correct answer then :) but I want a bound that is more limited in size.
It turns out, this is an interesting problem. The assumption I make is that for integer intervals, modulo is defined with respect to truncated division (round towards 0).
As a consequence, mod(-a,m) == -mod(a,m) for all a, m. Moreover, sign(mod(a,m)) == sign(a).
Definitions, before we start
Closed interval from a to b: [a,b]
Empty interval: [] := [+Inf,-Inf]
Negation: -[a,b] := [-b,-a]
Union: [a,b] u [c,d] := [min(a,c),max(b,d)]
Absolute value: |m| := max(m,-m)
Simpler Case: Fixed modulus m
It is easier to start with a fixed m. We will later generalize this to the modulo of two intervals. The definition builds up recursively. It should be no problem to implement this in your favorite programming language. Pseudocode:
def mod1([a,b], m):
// (1): empty interval
if a > b || m == 0:
return []
// (2): compute modulo with positive interval and negate
else if b < 0:
return -mod1([-b,-a], m)
// (3): split into negative and non-negative interval, compute and join
else if a < 0:
return mod1([a,-1], m) u mod1([0,b], m)
// (4): there is no k > 0 such that a < k*m <= b
else if b-a < |m| && a % m <= b % m:
return [a % m, b % m]
// (5): we can't do better than that
else
return [0,|m|-1]
Up to this point, we can't do better than that. The resulting interval in (5) might be an over-approximation, but it is the best we can get. If we were allowed to return a set of intervals, we could be more precise.
General case
The same ideas apply to the case where our modulus is an interval itself. Here we go:
def mod2([a,b], [m,n]):
// (1): empty interval
if a > b || m > n:
return []
// (2): compute modulo with positive interval and negate
else if b < 0:
return -mod2([-b,-a], [m,n])
// (3): split into negative and non-negative interval, compute, and join
else if a < 0:
return mod2([a,-1], [m,n]) u mod2([0,b], [m,n])
// (4): use the simpler function from before
else if m == n:
return mod1([a,b], m)
// (5): use only non-negative m and n
else if n <= 0:
return mod2([a,b], [-n,-m])
// (6): similar to (5), make modulus non-negative
else if m <= 0:
return mod2([a,b], [1, max(-m,n)])
// (7): compare to (4) in mod1, check b-a < |modulus|
else if b-a >= n:
return [0,n-1]
// (8): similar to (7), split interval, compute, and join
else if b-a >= m:
return [0, b-a-1] u mod2([a,b], [b-a+1,n])
// (9): modulo has no effect
else if m > b:
return [a,b]
// (10): there is some overlapping of [a,b] and [n,m]
else if n > b:
return [0,b]
// (11): either compute all possibilities and join, or be imprecise
else:
return [0,n-1] // imprecise
Have fun! :)
Let see mod(x, y) = mod.
In general 0 <= mod <= y. So it's always true: y_lo < mod < y_hi
But we can see some specific cases below:
- if: x_hi < y_lo then div(x, y) = 0, then x_low < mod < x_hi
- if: x_low > y_hi then div(x, y) > 0, then y_low < mod < y_hi
- if: x_low < y_low < y_hi < x_hi, then y_low < mod < y_hi
- if: x_low < y_low < x_hi < y_hi, then y_low < mod < x_hi
- if: y_low < x_low < y_hi < x_hi, then y_low < mod < y_hi
....
I have a 2-dimensional array that looks like this:
1 1 0 0 1
1 0 1 1 0
0 0 1 1 0
1 1 0 1 1
0 0 1 1 1
I'm trying to figure out a way to identify the longest contiguous chain of 1's going either across or down. In this case, it starts at column 4, row 2, and its length is 4, going down.
I was thinking of using recursion, but I'm running into some issues keeping track of position, especially when encountering a 0.
So far, I have something along the lines of this (for checking across only):
main() {
...
for(i = 0; i < n; i++)
for(j = 0; j < n; j++)
if (G[i][j] == 1) {
CheckAcross(i, j, n);
}
...
}
void CheckAcross (int i, int j, int n) {
if (i < 0 || i >= n || j < 0 || j >= n) return; // outside of grid
if (G[i][j] == 0 ) return; //0 encountered
G[i][j] = WordCount + 1;
CheckAcross(i, j + 1, n);
}
where G[][] is the 2-dimensional array containing the 1's and 0's, n is the number of rows/columns, i is the row number and j is the column number.
Thanks for any assistance in advance!
Your current answer will take O(n3) time; to evaluate a single line, you check every possible start and end position (O(n) possibilities for each), and there are n lines.
Your algorithm is correct, but let's see if we can improve on the running time.
The problem might become simpler if we break it into simpler problems, i.e. "What is the longest contiguous chain of 1s in this 1-dimensional array?". If we solve it 2n times, then we have our answer, so we just need to get this one down to smaller than O(n2) for an improvement.
Well, we can simply go through the line, remembering the position (start and end) and length of the longest sequence of 1s. This takes O(n) time, and is optimal (if the sequence is all 1s or 0s, we would have to read every element to know where the start/end of the longest sequence is).
Then we can simply solve this for every row and every column, in O(n2) time.
Create a new n-by-n matrix called V. This will store, for each cell, the number of 1s at that cell and immediately above it. This will be O(n^2).
checkAllVertical(int n) {
V = malloc(....) // create V, an n-by-n matrix initialized to zero
for(int r=0; r<n; r++) {
for(int c=0; c<n; c++) {
if(G[r][c]=1) {
if(r==0)
V[r][c] = 1;
else
V[r][c] = 1 + V[r][c];
}
}
}
}
You don't really need to allocate all of V. One row at a time would suffice.