0

I use cplex Java API.

Following code is used:

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

So I just use two boolean vectors x and y. This snippet works fine for smaller instances where inst.getSize() is, for instance, 25. However, for an instance of size 40 it crashes in the last line.

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)

Have you got any ideas? I need to get it working...

Stasik
  • 2,568
  • 1
  • 25
  • 44
  • I am not familiar with Java API, but in the .net API cplex.BoolVarArray() allready creates and adds the boolean variables to the model. By calling cplex.boolvar you create another boolean variable. I.e., you don't need the first two for loops. – willem May 10 '12 at 14:58
  • On a side note, you are aware that there a no constraints in your model, right? I assume you are planning to add them later? – willem May 10 '12 at 15:00
  • @willem, well but they should not crash – Stasik May 12 '12 at 17:52
  • @willem, contratints are in a later code which is not posted ) – Stasik May 12 '12 at 17:52
  • I am not sure, but having variables in the model to which you don't have references is not a good idea, and might cause problems. See my answer – willem May 14 '12 at 16:33

2 Answers2

1

Well after some trial and errors i found out that this is a kind of a memory issue.

Adding sufficient heapspace to JVM e.g. -Xms512M -Xmx750M solves the problem and lets the program to run as expected.

Stasik
  • 2,568
  • 1
  • 25
  • 44
0

You create and add Boolean Variables to the model by calling

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

you then add new variables to the formulation by calling

x[i] = cplex.boolVar();

but the old variables are still in the formulation, though you don't have references to them anymore. This might cause problems, and it is definitely not something you will want. I am not sure how to do this properly in Java, but in .net I would do either

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

or

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

(IIntVar is the .net variant of java IloIntVar). Same for y. Try commenting out the first two for loops, and see what happens to the error.

willem
  • 2,617
  • 5
  • 26
  • 38
  • it did not help, however i found something else :) – Stasik May 14 '12 at 19:21
  • @Stasik Ok, but did your program keep working for small .size() after the change? If so, i would recommend implementing the changes, for the mentioned reasons. – willem May 15 '12 at 20:27
  • yes, the behavior did not change. I did removed the loops. However, Java's garbage collector should should have removed the unused variables... Am I right? – Stasik May 18 '12 at 16:34
  • @stasik Note that Cplex still would have references to the variables, as it would still consider them part of the model. So if Java would try to remove the unused variables, you might get strange behavior/ errors. That's why I stress that it is not a good idea to have variables in Cplex to which you no longer have references in java. – willem May 22 '12 at 19:04