Search code examples
mathematical-optimizationlinear-programmingcplexinteger-programming

cplex boolVarArray giving double values


I have been trying to implement an ILP using CPLEX Java and have been stuck at a problem for a long time. Here are few variables of the ILP:

IloIntVar above = new IloIntVar[numRect][];
IloIntVar below = new IloIntVar[numRect][];
IloIntVar left = new IloIntVar[numRect][];
IloIntVar right = new IloIntVar[numRect][]; 

for (int i = 0; i < numRect; i++) {
        above[i] = cplex.boolVarArray(numRect);
        below[i] = cplex.boolVarArray(numRect);
        left[i] = cplex.boolVarArray(numRect);
        right[i] = cplex.boolVarArray(numRect);
}

The value of numRect is 1. At the end of the program I output these values:

for (int i = 0; i < numRect; i++) {
            for (int j = i + 1; j < numRect; j++) {
                System.out.println(cplex.getValue(left[i][j]));
                System.out.println(cplex.getValue(right[i][j]));
                System.out.println(cplex.getValue(above[i][j]));
                System.out.println(cplex.getValue(below[i][j]));
                System.out.println(cplex.getValue(left[i][j]) +
                                   cplex.getValue(right[i][j]) +
                                   cplex.getValue(above[i][j]) +
                                   cplex.getValue(below[i][j]));
            }
        }

Here is the output I get:

0.0
0.0
9.313225750491594E-10
0.9999999990686774
1.0

I do not understand why am I getting double values instead of booleans. Any help would be appreciated. Thanks.


Solution

  • The IloBoolVar is simply a IloNumVar constrained to be 0 or 1. By default, anything within 0.00001 of 0 or 1 is considered to be an integer. You can change this by setting the parameter EpInt. The parameter could be set to zero, but you are inviting performance issues. It is the best practice to round the values. In fact, any time you are working with floating point numbers, you need to be aware of rounding issues like this.