CPLEX ILOG OPL Optimization - c++

The model is optimizing the costs of Machines in Cell layout design
regarding the duplication and subcontracting.
Mod Const. is,
forall (k in 1..Cells, i in 1..nbMachines, j in 1..nbComps)
{
if (U[i][j][k] == 1 && A[k][i] < ((D[k][j]*S[k][j])*52))
DN[i][j][k] == 1;
SC[i][j][k] == 0;
INT[i][j][k] == 0;
}
forall (k in 1..Cells, i in 1..nbMachines, j in 1..nbComps)
{
if (V[i][j][k] == 1 && A[k][i] >= ((D[k][j]*S[k][j])*52))
DN[i][j][k] == 0;
SC[i][j][k] == 1;
INT[i][j][k] == 1;}
U , V are extracted in previous steps, A, D, S are input data.
The variables reqd. are DN, SC and INT.
Errors are those expressions are cannot be extracted, U, V are unbounded,
Please help in this regard,

Since U and V are decision variables, you should not write:
if (U[i][j][k] == 1 && A[k][i] < ((D[k][j]*S[k][j])*52))
DN[i][j][k] == 1;
Instead write:
((U[i][j][k] == 1) && (A[k][i] <= -1+((D[k][j]*S[k][j])*52)))
=> (DN[i][j][k] == 1);

Related

how to fix hamming weight invariants

I am learning Dafny, attempting to write a specification for the hamming weight problem, aka the number of 1 bits in a number. I believe I have gotten the specification correct, but it still doesn't verify. For speed of verification I limited it to 8 bit numbers;
problem definition: https://leetcode.com/problems/number-of-1-bits/
function method twoPow(x: bv16): bv16
requires 0 <= x <= 16
{
1 << x
}
function method oneMask(n: bv16): bv16
requires 0 <= n <= 16
ensures oneMask(n) == twoPow(n)-1
{
twoPow(n)-1
}
function countOneBits(n:bv8): bv8 {
if n == 0 then 0 else (n & 1) + countOneBits(n >> 1)
}
method hammingWeight(n: bv8) returns (count: bv8 )
ensures count == countOneBits(n)
{
count := 0;
var i := 0;
var n' := n;
assert oneMask(8) as bv8 == 255; //passes
while i < 8
invariant 0 <= i <= 8
invariant n' == n >> i
invariant count == countOneBits(n & oneMask(i) as bv8);
{
count := count + n' & 1;
n' := n' >> 1;
i := i + 1;
}
}
I have written the same code in javascript to test the behavior and example the invariant values before and after the loop. I don't seen any problems.
function twoPow(x) {
return 1 << x;
}
function oneMask(n) {
return twoPow(n)-1;
}
function countOneBits(n) {
return n === 0 ? 0 : (n & 1) + countOneBits(n >> 1)
}
function hammingWeight(n) {
if(n < 0 || n > 256) throw new Error("out of range")
console.log(`n: ${n} also ${n.toString(2)}`)
let count = 0;
let i = 0;
let nprime = n;
console.log("beforeloop",`i: ${i}`, `n' = ${nprime}`, `count: ${count}`, `oneMask: ${oneMask(i)}`, `cb: ${countOneBits(n & oneMask(i))}`)
console.log("invariants", i >= 0 && i <= 8, nprime == n >> i, count == countOneBits(n & oneMask(i)));
while (i < 8) {
console.log("");
console.log('before',`i: ${i}`, `n' = ${nprime}`, `count: ${count}`, `oneMask: ${oneMask(i)}`, `cb: ${countOneBits(n & oneMask(i))}`)
console.log("invariants", i >= 0 && i <= 8, nprime == n >> i, count == countOneBits(n & oneMask(i)));
count += nprime & 1;
nprime = nprime >> 1;
i++;
console.log('Afterloop',`i: ${i}`, `n' = ${nprime}`, `count: ${count}`, `oneMask: ${oneMask(i)}`, `cb: ${countOneBits(n & oneMask(i))}`)
console.log("invariants", i >= 0 && i <= 8, nprime == n >> i, count == countOneBits(n & oneMask(i)));
}
return count;
};
hammingWeight(128);
All invariants evaluate as true. I must be missing something. it says invariant count == countOneBits(n & oneMask(i) as bv8); might not be maintained by the loop. Running the javascript shows that they are all true. Is it due to the cast of oneMask to bv8?
edit:
I replaced the mask function with one that didn't require casting and that still not resolve the problem.
function method oneMaskOr(n: bv8): bv8
requires 0 <= n <= 8
ensures oneMaskOr(n) as bv16 == oneMask(n as bv16)
{
if n == 0 then 0 else (1 << (n-1)) | oneMaskOr(n-1)
}
One interesting thing I found is that it shows me a counter example where it has reached the end of the loop and the final bit of the input variable n is set, so values 128 or greater. But when I add an assertion above the loop that value equals the count at the end of the loop it then shows me the another value of n.
assert 1 == countOneBits(128 & OneMaskOr(8)); //counterexample -> 192
assert 2 == countOneBits(192 & OneMaskOr(8)); //counterexample -> 160
So it seems like it isn't evaluating the loop invariant after the end of loop? I thought the whole point of the invariants was to evaluate after the end of loop.
Edit 2:
I figured it out, apparently adding the explicit decreases clause to the while loop fixed it. I don't get it though. I thought Dafny could figure this out.
while i < 8
invariant 0 <= i <= 8
invariant n' == n >> i
invariant count == countOneBits(n & oneMask(i) as bv8);
decreases 8 - i
{
I see one line in the docs for loop termination saying
If the decreases clause of a loop specifies *, then no termination check will be performed. Use of this feature is sound only with respect to partial correctness.
So is if the decreases clause is missing does it default to *?
After playing around, I did find a version which passes though it required reworking countOneBits() so that its recursion followed the order of iteration:
function countOneBits(n:bv8, i: int, j:int): bv8
requires i ≥ 0 ∧ i ≤ j ∧ j ≤ 8
decreases 8-i {
if i == j then 0
else (n&1) + countOneBits(n >> 1, i+1, j)
}
method hammingWeight(n: bv8) returns (count: bv8 )
ensures count == countOneBits(n,0,8)
{
count ≔ 0;
var i ≔ 0;
var n' ≔ n;
//
assert count == countOneBits(n,0,i);
//
while i < 8
invariant 0 ≤ i ≤ 8;
invariant n' == n >> i;
invariant count == countOneBits(n,0,i);
{
count ≔ (n' & 1) + count;
n' ≔ n' >> 1;
i ≔ i + 1;
}
}
The intuition here is that countOneBits(n,i,j) returns the number of 1 bits between i (inclusive) and j (exclusive). This then reflects what the loop is doing as we increase i.

problem with writing if statement using Boolean variable in CPLEX

here is a part of my cplex code. i defined the PreReq as boolean variable but in the constraint i get the error for PreReq that "expression must have bool type" what am i doing wrong?
IloBoolVarArray2 PreReq(env), CoRec(env), Offered(env);
//Constraint 6: if course d is taken and course c is its pre-req, then course c must be taken before d
IloExpr constraint6a(env);
IloExpr constraint6b(env);
IloExpr constraint6c(env);
IloExpr constraint6d(env);
for (c = 0; c < NumberOfCourses; c++) {
for (d = 0; d < NumberOfCourses; d++) {
if (PreReq[c][d] == 1 ) {
for (s = 0; s < NumberOfSemesters; s++) {
constraint6a += X[d][s];
constraint6b += X[c][s];
constraint6c += s*X[c][s];
constraint6d += s*X[d][s];
}
}
}
mod.add(constraint6a <= constraint6b);
mod.add(constraint6c <= constraint6d + (NumberOfSemesters)*(1 - onstraint6a) );
constraint6a.end();
constraint6b.end();
constraint6c.end();
constraint6d.end();
}
You'd rather use IloIfThen (logical constraints)
The example in CPLEX documentation:
IloIfThen(env, (x >= y && x >= z), IloNot(x <= 300 || y >= 700))
Expanding on Alex's answer: your problem is that you are mixing constraints with constraint generation: In the statement if ( PreReq[c][d] == 1 ) the operator== is overloaded to generate a constraint that requires PreReq[c][d] to take the value 1. So the result in this expression is of type IloConstraint, which is not a boolean type (it is a constraint object instead). That is why you get the error message. What you want instead is to add a constraint to your model that requires additional constraints in case PreReq[c][d] is 1.
So you probably want something like this:
for (d = 0; d < NumberOfCourses; d++) {
for (s = 0; s < NumberOfSemesters; s++) {
mod.add(IloIfThen(PreReq[c][d] == 1, constraint6a + X[d][s] <= constraint6b + X[c][s]));
mod.add(IloIfThen(PreReq[c][d] == 0, constraint6a <= constraint6b));
}
}
Which adds two variants of the constraint, only one of which will ever be active (depending on the value of PreReq[c][d]). Also see the reference documentation of class IloIfThen.

C++ upper_bound on struct vector with == operator

I have following struct,
struct cube
{
int index l , b , h;
bool operator<(const cube & c2) const
{
if (l == c2.l && b == c2.b && h == c2.h)
return index < c2.index;
if (l == c2.l && b == c2.b)
return h < c2.h;
if (l == c2.l )
return b < c2.b;
return l < c2.l;
}
bool operator==(const cube c2)
{
return index != c2.index && l == c2.l && b == c2.b;
}
};
Now I want to apply upper_bound on vector of this struct as per condition in == operator.
However , it is still returning me those iterators where index are same
int pos2 = upper_bound(v.begin(),v.end(),v[i]) - v.begin();
i.e v[i].index is equal to v[pos2].index
It's possible that for two cube instances foo and bar that foo < bar is true when foo == bar is also true. You could fix that by writing index == c2.index && l == c2.l && b == c2.b as the returned expression in operator==.
This contradiction is the root cause of your issues, although note that std::upper_bound does itself only require that operator< is implemented appropriately; which yours is.
Isn't index more of a property of a collection of cubes rather than a given cube? That is, it shouldn't appear in the cube class?

Are semicolon-terminated if-statements good coding practice?

I am looping i, j, k and n. I want a statement to execute except when k == j and n == k.
If I use the code like this:
if (k != j && n != i)
//statement
The statement will not execute in two cases:
When k != j when n == j.
When k == j when n != j. (which is not what I need)
So I used a code like this:
if (k == j && n == i)
;else
//statement
By this code the statement will successfully execute except when k == j && n == i.
Is semicolon-terminated if-statements is a good way of coding in C++?
No it's not a good way of coding. The usual way is to use ! to invert the logic:
if(!(k==j && n==i))
//statement
Or you could use De Morgan's Law to invert the logic:
if(k!=j || n!=i)
//statement
Your problem is that you're negating the condition incorrectly. You should just do:
if (!(k==j && n==i))
// statement
Or, by De Morgan's laws:
if (k != j || n != i)
// statement
... is a good way of coding?
No.
You should write
if (!(k == j && n == 1))
{
//statement
}
Putting a semicolon after an if, for, or while is almost always wrong. It is highly unexpected and makes reading your code very difficult.

How || and && works [duplicate]

This question already has answers here:
Logical Operators in C
(8 answers)
Closed 9 years ago.
main( ) {
int i = 4, j = -1, k = 0, w, x, y, z ;
w = i || j || k ;
x = i && j && k ;
y = i || j && k ;
z = i && j || k ;
printf ( "\nw = %d x = %d y = %d z = %d", w, x, y, z ) ;
}
I'm just learning C and I came across this code. I honestly dont know what w, x, y and z are assigned to. Apparently the output is as follows:
w = 1 x = 0 y = 1 z = 1
How is 'w' equal to 1? I dont get it.
|| is the logical OR operator. From C11 s6.5.14 Logical OR operator
The || operator shall yield 1 if either of its operands compare
unequal to 0; otherwise, it yields 0. The result has type int.
...the || operator guarantees left-to-right evaluation;
Applying this to the calculation for w we get
w = i || j || k == (i || j) || k
== (non-zero || non-zero) || 0
== 1 || 0
== 1
Calculations for x, y, z are similar. C11 s6.5.13.3 states that the result from the && operator shall be 0 or 1.
In C there is no "strong" built-in type for Boolean values, so integers are used instead. Results of evaluating logical expressions, such as ones using || and &&, can be assigned to integer variables.
When a value is used in a logical operator, the Boolean interpretation is very straightforward: zeros are interpreted as false, while all non-zero values are interpreted as true.
Now you should be able to figure out the expressions for yourself:
i || j || k evaluates as 1, because i and j are not zeros
i && j && k evaluates as 0, because k is zero,
...and so on.
This is how conceptually it works:
w = i || j || k;
w = 4 || -1 || 0; //values replaced
w = true || 0; //4 || -1 evaluates to true
w = (true); //true is being assigned to integer
w = 1; //0 is false, 1 is for true
It is logical operations.
|| - means logical or, if at least one element is not 0, result is 1, otherwise its 0;
&& - means logical and, if all elements are 1, result is 1, otherwise its 0;
Logical and has higher priority, so:
x = 0 || 4 && 0;
Would be 0, because:
4&&0 = 0
0||0 = 0.
These operators are about full value of number. There are | and & operators connected with bits.
Everything about working and priority is the same, just short example:
uint8_t x = 2 || 4 && 7;
1. 4=00000100 and 7=00000111
00000100
& 00000111
gives:00000100
2. 2=00000010
00000010
| 00000100
gives:00000110, it is 6
I hope it is helpful.
|| is the logical OR.
w = i || j || k;
is equivalent to:
w = (i != 0) || (j != 0) || (k != 0);
i is 4, which explains that w is true (which is evaluated to 1 as C uses integers to deal with booleans).
The same is applicable to && (the logical AND), etc.