LazyConstraintCallback

时间:2018-01-30 13:59:41

标签: java cplex

我是CPLEX + Java的新手。我尝试实现Orienteering Problem和Pickup and Delivery问题的变体。我想使用LazyConstraintCallback来确保Integer Solutions中的Subtour Elimination。

由于定向运动组件,我需要一个额外的变量(z [q])in for Callback,到目前为止还没有包含在模型中。

protected void main() throws IloException {
        // first: test if more than one route exists
        int[][] cycles = getCycles(getLongRoute());
        int count = countCycles(cycles);
        IloNumVar[] z = model.boolVarArray(count);

        if (count > 1) {
            // add connectivity constraints
            int b = 1;
            for (int q = 0;q<cycles.length; q++) {
                IloLinearNumExpr expr1 = model.linearNumExpr();
                int[] cycle = cycles[q];
                int m = 0;
                for (int p = 0; p<cycle.length; p++) {
                    int i = ArrayHandler.getIndex(allLocations_k, cycle[p]);
                    for (int l = 0; l<cycle.length; l++) {
                        int j = ArrayHandler.getIndex(allLocations_k, cycle[l]);
                        if (i!=j) {
                            expr1.addTerm(1.0, x[i][j]);
                        }
                    }
                    if (ArrayHandler.contains(deliveryLocation_k, allLocations_k[i])) {
                        expr1.addTerm(ak[i], 1.0);
                    } else {
                        m++;
                        expr1.addTerm(ak[i], -1.0);
                    }
                }

                for (int p = 0; p<loc_k; p++) {
                    int i = allLocations_k[p];
                    if (!ArrayHandler.contains(cycle, i)) {
                        IloLinearNumExpr expr2 = model.linearNumExpr();
                        if (ArrayHandler.contains(deliveryLocation_k, i)) {
                            expr2.addTerm(ak[p], 1.0);
                            expr2.addTerm(z[q],-1.0);
                            this.add(model.le(expr2,0.0));
                            //this.addLe(expr2, z[q]);
                        } else {
                            expr2.addTerm(ak[p], 1.0);
                            expr2.addTerm(z[q], 1.0);
                            this.add(model.ge(expr2,1.0));
                            //model.addLe(1.0,expr2);
                        }
                    }
                }

                expr1.setConstant(m);
                expr1.addTerm(z[q], -1.0);
                this.add(model.le(0.0, expr1));
            }
        }
    }

在读取“this.add(model.ge(expr2,z [q]));”后抛出“未知对象”错误,这是它应该添加的第一个约束。我猜这个行为以某种方式连接到未知变量z [q]。我必须在其他地方添加吗?我不知道z [q]的最终维度,因为我需要为执行期间找到的每个子索获得z [q],这可能会呈指数级增长(这就是为什么我希望能够动态创建它)。 也许错误信息有帮助:

ilog.cplex.IloCplex$UnknownObjectException: CPLEX Error: object is unknown to IloCplex
at ilog.cplex.CpxNumVar.getVarIndexValue(CpxNumVar.java:295)
at ilog.cplex.CpxLinearExpr.removeDuplicatesSafe(CpxLinearExpr.java:476)
at ilog.cplex.CpxCutCallback.addCut(CpxCutCallback.java:75)
at ilog.cplex.IloCplex$LazyConstraintCallback.add(IloCplex.java:14920)
at PDOP$IntegerCutCallback.main(PDOP.java:334)
at ilog.cplex.CpxCallback.callmain(CpxCallback.java:160)
at ilog.cplex.CpxLazyConstraintCallbackFunction.callIt(CpxLazyConstraintCallbackFunction.java:45)
at ilog.cplex.Cplex.CPXmipopt(Native Method)
at ilog.cplex.CplexI$SolveHandle.start(CplexI.java:2786)
at ilog.cplex.CplexI.solve(CplexI.java:2912)
at ilog.cplex.IloCplex.solve(IloCplex.java:10434)
at PDOP.solveIBR(PDOP.java:193)
at Application.main(Application.java:33)

我希望这不是“太”愚蠢的问题,我试图在网上找到这种行为的东西,但没有找到任何需要添加变量的例子。

1 个答案:

答案 0 :(得分:1)

我继续阅读它,好像根本不可能在LazyConstraint中添加其他变量(https://www.or-exchange.org/questions/14311/adding-variables-or-modifying-existing-constraints-during-callbacks-with-cplex-c

我能够重新解决我的问题(它不简洁易读,但有效......),它比直接在问题中直接包含地形消除约束更快,并且仍然可以产生可行的解决方案。

感谢rkersh的帮助:)