如何访问 CPLEX 中的最终单纯形图?

How to access the final simplex tableau in CPLEX?

我正在使用 Java API 通过 CPLEX 求解 LP。我使用提供的方法(如 cplex.numVar(col, lb, ub)cplex.addLe())构建我的模型优化完成后,我有兴趣阅读最终迭代的单纯形画面(准确地说:不仅是对偶和降低了成本,但也降低了表格中的系数)。

我试图访问 IloLPMatrix 对象 cplex.LPMatrix(),但这只是 returns 一个空矩阵。我对与我刚刚解决的问题相关的“填充”矩阵感兴趣。

那么,我该如何阅读单纯形图呢?

CPLEX_Studio128\cplex\examples\src\java 中,您可以查看示例 LPex1.java

简短的回答是您不能 使用 Concert (Java/.NET/C++) API 访问单纯形画面。不过,您可以使用 C Callable Library 和 Python API 访问此高级功能。例如,参见 CPXXbinvarow and examining the simplex tableau in the Python API.

现在,为了消除您对 IloLPMatrix 所做的事情可能产生的混淆,请考虑以下内容(大部分摘自 IBM developerWorks 官方论坛上的 this 主题)。

如果使用 cplex.addLe() 向模型添加约束,则可以使用 rangeIterator to access them (and possibly conversionIterator, SOS1Iterator, SO2Iterator)。请注意,当您使用 rangeIterator 时,您必须先弄清楚表达式的运行时类型,然后才能获得系数。例如:

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 ...) {
      ...
   }
}

另一方面,如果您使用 IloLPMatrix, then you can access it with LPMatrixIterator. When you call cplex.LPMatrix it "Creates and returns an empty LP matrix object." You then have to fill it and add it to the model. Alternately, you can use addLPMatrix 构建模型以一步创建和添加它(您仍然需要填充它)。

例如:

// 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);

请注意,您只能在使用 IloLPMatrix 时添加线性约束。

无论您是使用第一种方法构建模型并 rangeIterator 访问它,还是使用第二种方法和 LPMatrixIterator,都是个人喜好问题,可能还需要一些性能权衡;您必须尝试两种方法。