I have been working on a combinatorial optimization problem which can be modeled as an integer linear programming. I implemented it as a c++ project in visual studio 2017 and CPLEX1271. Since there are exponentially many constraints, I implemented lazy constraints by IloCplex::LazyConstraintCallbackI. In my mind the following procedure is how an optimal soution is produced: everytime an integer solution is identified, LazyConstraintCallbackI will check it and add some violated constraints to the model untill an optimal integer solution is obtained.
However, the objective values given by my implementation for different inputs are not always correct. After almost one year's intermittent debug and test, I finally figured out the reason, which is very problem related but can be explained(hopefully) by the following tiny example: an integer linear programming involving four bool variables x1, x2, x3 and x4
minimize x1
subject to:
x1 ≥ x2
x1 ≥ x3
x1 ≥ x4
x2 + x3 ≥ 1
x1, x2, x3 and x4 ∈ {0, 1}
The result given by cplex is:
Solution status = Optimal
Objective value = 1
x1 = 1
x2 = 1
x3 = 1
x4 = 1
Undoubtedly, the objective value is correct .The weird thing is that cplex sets x4 = 1. Although whether x4 equals 1 or 0 has no impact on the objective value in this programming. But, when lazy constraint callback is used, this could lead to a problem by adding some incorrect contraint and integer programming is solved by iteratively adding violated constraints. I'd like to know:
- why cplex set "unrelated" variable x4 as 1, instead of 0?
- What should I do to tell CPLEX that I want to leave such "unrelated" variable as 0?