0

我使用cplex Java API。大數組上的Cplex NullPointerException

下面的代碼是使用:

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

你有什麼想法嗎?我需要得到它的工作...

+0

我對Java API不熟悉,但在.net API中cplex.BoolVarArray()已經創建並將布爾變量添加到模型中。通過調用cplex.boolvar可以創建另一個布爾變量。也就是說,你不需要前兩個循環。 – willem

+0

在附註中,您知道模型中沒有限制,對吧?我假設你打算在以後添加它們? – willem

+0

@ willem,好吧,但他們不應該崩潰 – Stasik

回答

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循環,並查看錯誤發生了什麼。

+0

它沒有幫助,但是我發現了其他東西:) – Stasik

+0

@Stasik好了,但是你的程序在改變之後繼續爲小的.size()工作嗎?如果是這樣,我會建議實施更改,爲上述原因。 – willem

+0

是的,行爲沒有改變。我沒有刪除循環。但是,Java的垃圾收集器應該已經刪除了未使用的變量......我是對的嗎? – Stasik

1

經過一些試驗和錯誤,我發現這是一種內存問題。

爲JVM添加足夠的堆空間,例如-Xms512M -Xmx750M解決了這個問題並讓程序按預期運行。