0

我使用 cplex Java API。

使用以下代码:

//init cplex
IloCplex cplex = new IloCplex();
cplex.setParam(IloCplex.IntParam.Threads, 1);
//is commodity k,l routed over i and j
//x ijkl
IloIntVar[] x = cplex.boolVarArray(inst.getSize()*inst.getSize()*inst.getSize()*inst.getSize());
for (int i = 0; i < x.length; i++) {
    x[i] = cplex.boolVar();
}

//is node a hub
IloIntVar[] y = cplex.boolVarArray(inst.getSize());
for (int i = 0; i < y.length; i++) {
    y[i] = cplex.boolVar();
}

//=== FITTNESS FUNCTION ===
IloLinearNumExpr expr = cplex.linearNumExpr();
//first big sum
for(int k=0;k<inst.getSize();k++){
    for(int i=0;i<inst.getSize();i++) {
        for(int j=0;j<inst.getSize();j++) {
            for(int l=0;l<inst.getSize();l++) {
                expr.addTerm(c[i][j][k][l], x[Static.quadToLinear(i, j, k, l, inst.getSize())]);
            }
        }
    }
}
//second sum
for(int i=0;i<inst.getSize();i++) {
    expr.addTerm(inst.getFixed(i), y[i]);
}
//minimise it
cplex.addMinimize(expr);

所以我只使用两个布尔向量 x 和 y。此代码段适用于 inst.getSize() 为例如 25 的较小实例。但是,对于大小为 40 的实例,它在最后一行崩溃。

Exception in thread "main" java.lang.NullPointerException
at ilog.cplex.CpxNumVar.unmark(CpxNumVar.java:296)
at ilog.cplex.CpxLinearExpr.unmarkVars(CpxLinearExpr.java:402)
at ilog.cplex.CpxLinearExpr.removeDuplicates(CpxLinearExpr.java:515)
at ilog.cplex.CpxLinearExpr.removeDuplicates(CpxLinearExpr.java:489)
at ilog.cplex.CpxObjective.setExpr(CpxObjective.java:108)
at ilog.cplex.CpxObjective.<init>(CpxObjective.java:362)
at ilog.cplex.IloCplexModeler.objective(IloCplexModeler.java:706)
at ilog.cplex.IloCplexModeler.addObjective(IloCplexModeler.java:768)
at ilog.cplex.IloCplexModeler.addMinimize(IloCplexModeler.java:790)
at ExactSolver.main(ExactSolver.java:69)

你有什么想法吗?我需要让它工作...

4

2 回答 2

1

经过一些试验和错误后,我发现这是一种内存问题。

向 JVM 添加足够的堆空间,例如 -Xms512M -Xmx750M 可以解决问题并让程序按预期运行。

于 2012-05-14T19:23:35.083 回答
0

您可以通过调用创建布尔变量并将其添加到模型中

IloIntVar[] x = cplex.boolVarArray
    (inst.getSize()*inst.getSize()*inst.getSize()*inst.getSize());

然后,您通过调用将新变量添加到公式中

x[i] = cplex.boolVar();

但是旧变量仍在公式中,尽管您不再引用它们。这可能会导致问题,而且绝对不是您想要的。我不确定如何在 Java 中正确执行此操作,但在 .net 中我会这样做

IIntvar[] x = new IIntvar[size];
for (int i = 0; i < x.length; i++) {
    x[i] = cplex.boolVar();
}

或者

IIntVar[] x=  cplex.BoolVarArray(size);
//No for loop!

(IIntVar 是 java IloIntVar 的 .net 变体)。对 y 相同。尝试注释掉前两个 for 循环,看看错误会发生什么。

于 2012-05-14T16:36:23.910 回答