Closed tasseff closed 3 years ago
Take note of the large warning in the JuMP documentation: https://jump.dev/JuMP.jl/stable/callbacks/#Available-solvers-1 JuMP's solver-independent callbacks are a useful abstraction of syntax. They do not guarantee equivalent behavior between solvers.
You should only submit a lazy constraint if the current solution is infeasible. Thus, your callback should be
function lazy_cut_callback(cb_data)
if callback_value(x) < 0.0
con = JuMP.@build_constraint(x >= 0.0)
MOI.submit(model, MOI.LazyConstraint(cb_data), con)
end
end
Closing since this is expected behavior.
Hi, I'm using LazyConstraintCallback in cplex via java with the following code and I'm getting a fatal error at runtime. Could you let me know what's causing this and how to fix it? public class LazyConstraintsExample { public static void main(String[] args) { try { IloCplex cplex = new IloCplex();
// Variables
IloIntVar x1 = cplex.boolVar("x1");
IloIntVar x2 = cplex.boolVar("x2");
IloIntVar x3 = cplex.boolVar("x3");
// Objective: maximize x1 + 2x2 + 3x3
cplex.addMaximize(cplex.sum(cplex.sum(x1, cplex.prod(2, x2)), cplex.prod(3, x3)));
// Constraint: 2x1 + x2 + x3 <= 4
cplex.addLe(cplex.sum(cplex.sum(cplex.prod(2, x1), x2), x3), 4);
//cplex.addLe(cplex.sum(x1,x2), 1);
// Add lazy constraint callback
cplex.use(new MyLazyCallback(x1,x2,cplex));
// Solve the model
if (cplex.solve()) {
System.out.println("Solution status: " + cplex.getStatus());
System.out.println("Objective value: " + cplex.getObjValue());
System.out.println("x1 = " + cplex.getValue(x1));
System.out.println("x2 = " + cplex.getValue(x2));
System.out.println("x3 = " + cplex.getValue(x3));
} else {
System.out.println("No solution found");
}
cplex.end();
} catch (IloException e) {
e.printStackTrace();
}
}
} public class MyLazyCallback extends IloCplex.LazyConstraintCallback { IloNumVar x1; IloNumVar x2; IloCplex cplex;
MyLazyCallback(IloNumVar x1,IloNumVar x2,IloCplex cplex){
this.x1 = x1;
this.x2 = x2;
this.cplex = cplex;
}
@Override
protected void main() throws IloException {
double x1Val = getValue(x1);
double x2Val = getValue(x2);
System.out.println("x1:" + x1Val);
System.out.println("x2:" + x2Val);
// 检查是否违反了某个 Lazy 约束
if ( x1Val + x2Val > 1) {
// 创建并添加新的约束
IloLinearNumExpr expr = cplex.linearNumExpr();
expr.addTerm(1.0, x1);
expr.addTerm(1.0, x2);
//IloRange rng = cplex.range(Double.MIN_VALUE,expr,1);
IloRange rng = cplex.addLe(expr,1);
cplex.addLazyConstraint(rng);
System.out.println("Lazy constraint added: x + y <= 1");
}
}
} The error that occurs is shown in the figure
Hi @4YHa! Unfortunately, you are asking your question at the wrong place: this repo only contains the Julia wrapper for CPLEX, there is nothing about Java here. It is not affiliated with IBM. You can try on the official forum (https://community.ibm.com/community/user/ai-datascience/communities/community-home) or on Stack Exchange (https://or.stackexchange.com/).
@dourouc05 Thank you very much for your answer.
Currently, every time a constraint is added within a lazy cut callback, the MIP solution at the corresponding integer feasible node is removed from the solution space. There are circumstances where a feasible integer solution may be used to construct a cut that does not necessarily cut off that solution. I've found that the latter (expected) behavior is present in Gurobi.jl but not CPLEX.jl.
I expect this is being caused by the use of
CPXcallbackrejectcandidate
here, which automatically classifies the integer solution as infeasible within CPLEX. I'm not familiar enough with the C interface of CPLEX to suggest an alternative, but I'm hoping this can be addressed. Below is a small example that will result in infeasibility even though the lazy constraint that is being added should be inconsequential.