Originally posted by: SystemAdmin
When you add constraints to CPLEX via addGe() these constraints are not added to an instance of IloLPMatrix but are added to a list of instances of IloRange. I.e. the constraints of a model comprise of a list of IloLPMatrix and a list of IloRange instances (and some other lists).
These lists can be queried by IloCplex.LPMatrixIterator() and IloCplex.rangeIterator().
However, using the rangeIterator is a little ugly as you have to figure out the runtime type of the expression used in the range before you can get at the coefficients:
for (Iterator it = cplex.rangeIterator(); it.hasNext(); /* nothing */) {
IloRange range = (IloRange)it.next();
IloNumExpr expr = range.getExpr(); // Cannot get the coefficients of expr directly :-(
if (expr instanceof IloLinearNumExpr) {
IloLinearNumExpr linExpr = (IloLinearNumExpr)expr;
for (IloLinearNumExprIterator jt = linExpr.linearIterator(); jt.hasNext(); /* nothing */) {
IloNumVar var = jt.nextNumVar();
double coef = jt.getValue();
...
}
}
else if (expr instance of ...) {
...
}
}
Note that if you use the iterator approach described above you may also want to consider IloCplex.conversionIterator(), IloCplex.SOS1iterator() and IloCplex.SOS2iterator().
Another way to easily get at the coefficients via an IloLPMatrix would be building the model via this matrix. Assume you build your model like this
// Create variables.
IloNumVar x = cplex.numVar();
IloNumVar y = cplex.mumVar();
// Create constraint x + y <= 2.
IloLinearNumExpr lhs = cplex.linearNumExpr();
lhs.addTerm(x, 1.0);
lhs.addTerm(y, 1.0);
cplex.addLe(lhs, 2.0);
To setup the same model but get appropriate information in an instance of IloLPMatirx you do
// Create a matrix in which we setup the model.
IloLPMatrix matrix = cplex.LPMatrix();
// Create variables.
IloNumVar x = cplex.numVar();
IloNumVar y = cplex.numVar();
matrix.addCols(new IloNumVar[]{ x, y });
// Create constraint x + y <= 2.
IloLinearNumExpr lhs = cplex.linearNumExpr();
lhs.addTerm(x, 1.0);
lhs.addTerm(y, 1.0);
matrix.addRow(cplex.le(lhs, 2.0));
// When all constraints are setup add the matrix to the model.
cplex.add(matrix);
The steps to change your code are:
-
Allocate an instance of IloLPMatrix before you start creating variables/constraints.
-
Every time you create a variable add it to the matrix via addCols().
-
Instead of using addGe()/addLe()/addEq() to create and add a constraint use ge()/le()/eq() to only create the constraint and then add this constraint to the matrix via addRow().
-
When the matrix is completely setup use cplex.add(matrix) to add all constraints defined by the matrix.
Of course you can only add constraints with linear expressions to a matrix.
Note that the second step (adding columns to the matrix via addCols()) is optional as IloLPMatrix.addRow() will add missing variables to the matrix (see the documentation of this function).
#CPLEXOptimizers#DecisionOptimization