Java调用CPLEX求解LP:放宽最优性/获可行解参数无效问题
Hey there, let's break down why those parameters aren't making a difference in your test model and how to adjust your approach for your actual use case:
1. Why MIP.Limits.Solutions does nothing here
Your test model is a pure continuous Linear Program (LP)—all variables use numVar, meaning no integer constraints. The MIP.Limits.Solutions parameter is exclusively designed for Mixed Integer Programs (MIPs). It tells CPLEX to stop once it finds N feasible integer solutions, but since your model has no integer variables, CPLEX uses LP solvers (simplex/barrier) that completely ignore this parameter.
2. Why Simplex.Tolerances.Optimality shows no change
Your test LP is tiny and trivial—CPLEX can solve it to full precision in milliseconds. The optimality tolerance parameter lets CPLEX stop early when the current solution's objective is within a relative percentage of the true optimal value. But for such a simple model, the solver hits the exact optimal solution so fast that adjusting this tolerance doesn't save any measurable time. This parameter will only show an impact on large, complex LP models where finding the exact optimal solution takes significant time.
Fixes & Adjustments for Your Use Case
If your actual model is an LP (no integer variables):
To speed up solving or get a feasible solution early, use LP-specific parameters instead:
- Limit iterations or time: Use
cplex.setParam(IloCplex.Param.Simplex.Limits.Iterations, 1000);to stop after a set number of simplex iterations, orcplex.setParam(IloCplex.Param.Simplex.Limits.Time, 10);to cap solving time at 10 seconds. - Switch algorithms: Try a faster algorithm for your LP type—for example, use dual simplex with
cplex.setParam(IloCplex.Param.RootAlgorithm, IloCplex.Algorithm.Dual); - Provide an initial feasible solution: Use
cplex.start()to pass a known feasible solution, which can help the solver converge faster.
If your actual model is a MIP (has integer variables):
First, make sure your model includes integer variables (use intVar instead of numVar for some variables). Then MIP.Limits.Solutions will work as expected—setting it to 1 will make CPLEX stop as soon as it finds the first feasible integer solution, which is often much faster than finding the optimal one.
Example Modified Test Model (MIP)
Here's a tweak to your test code to turn it into a MIP, so you can see the MIP.Limits.Solutions parameter in action:
package cplexTest; import ilog.concert.*; import ilog.cplex.*; public class TestC { public static void main (String[] args) { model1(); } public static void model1() { try { IloCplex cplex = new IloCplex(); // For MIP: Stop after first feasible solution cplex.setParam(IloCplex.Param.MIP.Limits.Solutions, 1); // Make x an integer variable to convert this to a MIP IloNumVar x = cplex.intVar(0, Double.MAX_VALUE, "x"); IloNumVar y = cplex.numVar(0, Double.MAX_VALUE, "y"); IloLinearNumExpr objective = cplex.linearNumExpr(); objective.addTerm(0.12, x); objective.addTerm(0.15, y); cplex.addMinimize(objective); cplex.addGe(cplex.sum(cplex.prod(60, x), cplex.prod(60, y)),300); cplex.addGe(cplex.sum(cplex.prod(12, x), cplex.prod(6, y)),36); cplex.addGe(cplex.sum(cplex.prod(10, x), cplex.prod(30, y)),90); if (cplex.solve()) { System.out.println("obj = "+cplex.getObjValue()); System.out.println("x = "+cplex.getValue(x)); System.out.println("y = "+cplex.getValue(y)); // Check if this is a feasible solution or the optimal one System.out.println("Solution status: " + cplex.getStatus()); } else { System.out.println("Model not solved"); } cplex.end(); } catch (IloException exc) { exc.printStackTrace(); } } }
When you run this, CPLEX will stop after finding the first feasible integer solution (instead of optimizing to the true minimum), which should be noticeably faster for larger MIPs.
内容的提问来源于stack exchange,提问作者Georgios

