使用JavaCPLEX解决TSP时,变量的getValues会给出一个错误
我使用使用JavaCPLEX解决TSP时,变量的getValues会给出一个错误,java,cplex,getvalue,Java,Cplex,Getvalue,我使用cplex来解决旅行商问题(TSP)。 假设x[i][j]=1,则路径从城市i到城市j,否则,这些城市之间没有路径。 相应的矩阵: IloNumVar[][] x = new IloNumVar[n][]; for(int i = 0; i < n; i++){ x[i] = cplex.boolVarArray(n); } 但它给出了一个错误。我将感谢任何能给我一些建议的人。 错误在于: var[i][j] = cplex.getValue(x[i][j]); 解释如
cplex
来解决旅行商问题(TSP)。
假设x[i][j]=1
,则路径从城市i到城市j,否则,这些城市之间没有路径。
相应的矩阵:
IloNumVar[][] x = new IloNumVar[n][];
for(int i = 0; i < n; i++){
x[i] = cplex.boolVarArray(n);
}
但它给出了一个错误。我将感谢任何能给我一些建议的人。
错误在于:
var[i][j] = cplex.getValue(x[i][j]);
解释如下:
Exception in thread "main" ilog.cplex.IloCplex$UnknownObjectException: CPLEX Error: object is unknown to IloCplex
at ilog.cplex.IloCplex.getValue(IloCplex.java:6495)
整个代码如下所示:
import java.io.IOException;
import ilog.concert.*;
import ilog.cplex.IloCplex;
public class TSP {
public static void solveMe(int n) throws IloException, IOException{
//random data
double[] xPos = new double[n];
double[] yPos = new double[n];
for (int i = 0; i < n; i ++){
xPos[i] = Math.random()*100;
yPos[i] = Math.random()*100;
}
double[][] c = new double[n][n];
for (int i = 0 ; i < n; i++){
for (int j = 0 ; j < n; j++)
c[i][j] = Math.sqrt(Math.pow(xPos[i]-xPos[j], 2)+ Math.pow(yPos[i]-yPos[j],2));
}
//model
IloCplex cplex = new IloCplex();
//variables
IloNumVar[][] x = new IloNumVar[n][];
for(int i = 0; i < n; i++){
x[i] = cplex.boolVarArray(n);
}
IloNumVar[] u = cplex.numVarArray(n, 0, Double.MAX_VALUE);
//Objective
IloLinearNumExpr obj = cplex.linearNumExpr();
for(int i =0 ; i <n ; i++){
for (int j = 0; j< n ;j++){
if(j != i){
obj.addTerm(c[i][j], x[i][j]);
}
}
}
cplex.addMinimize(obj);
//constraints
for(int j = 0; j < n; j++){
IloLinearNumExpr expr = cplex.linearNumExpr();
for(int i = 0; i< n ; i++){
if(i!=j){
expr.addTerm(1.0, x[i][j]);
}
}
cplex.addEq(expr, 1.0);
}
for(int i = 0; i < n; i++){
IloLinearNumExpr expr = cplex.linearNumExpr();
for(int j = 0; j< n ; j++){
if(j!=i){
expr.addTerm(1.0, x[i][j]);
}
}
cplex.addEq(expr, 1.0);
}
for(int i = 1; i < n; i++){
for(int j = 1; j < n; j++){
if(i != j){
IloLinearNumExpr expr = cplex.linearNumExpr();
expr.addTerm(1.0, u[i]);
expr.addTerm(-1.0, u[j]);
expr.addTerm(n-1, x[i][j]);
cplex.addLe(expr, n-2);
}
}
}
//solve mode
if(cplex.solve()){
System.out.println();
System.out.println("Solution status = "+ cplex.getStatus());
System.out.println();
System.out.println("cost = " + cplex.getObjValue());
for(int i = 0; i<x.length; i++){
for(int j = 0 ; j < x[i].length; j ++){
System.out.print(cplex.getValue(x[i][j]));
}
}
}
//end
cplex.end();
}
}
import java.io.IOException;
导入ilog.concert.*;
导入ilog.cplex.IloCplex;
公共类TSP{
公共静态void solveMe(int n)抛出IloException,IOException{
//随机数据
double[]xPos=新的double[n];
double[]yPos=新的double[n];
对于(int i=0;igetValue()
的参数必须是用于构建您正在求解的模型的参数,如示例中所示。由于var
是nxn
,您可能应该将x
初始化为IloNumVar[]]x=new IloNumVar[n][n]
。在调用solve()
之前,应将x
的每个元素添加到您的模型中
在您的设置中,x
的对角线元素从未被模型引用。您会注意到,如果(i!=j),您的所有设置循环都有一个条件。若要解决您的问题,请在至少一个循环中添加一个else
子句,或者如果这没有意义(我怀疑是这样的话),打印输出是否与输入一致:
for(int i = 0; i<x.length; i++) {
for(int j = 0 ; j < x[i].length; j ++) {
if(i != j)
System.out.print(cplex.getValue(x[i][j]));
else
System.out.print("-");
}
}
for(int i=0;i“告诉我们错误消息的确切措辞”(摘自“如何询问”帮助:)发布初始化x
的代码,并将其添加到模型中。这才是真正导致错误的原因。您如何将x
与cplx
关联?您应该发布一个完整的最小示例,我们可以自己运行来重现错误。@Mad Physician我真的很感激您能共享时间来运行是。@Joyee。我没有机会运行代码,但我确实看到了一个我认为可以解决您问题的主要问题。答案已经更新。首先谢谢您。我已经在我的模型中添加了x:IloNumVar[][]x=new IloNumVar[n][];for(int I=0;I
如果我不获取变量的值,它可以解决问题。仅仅创建变量不一定足以将其提取到CPLEX中。只有实际出现在约束或目标中的变量才会提取到CPLEX中。因此,根据您构建模型的方式,可能没有任何约束包括您创建的一些变量。它是否在第一次循环时就失效了?是否存在关于x[0][0]的约束?@TimChippingtonDerrick。您是对的。根据发布的代码,遗漏非常明显。@TimChippingtonDerrick您是对的。我已经解决了这个问题。谢谢you@MadPhysicist.Thank你
for(int i = 0; i<x.length; i++) {
for(int j = 0 ; j < x[i].length; j ++) {
if(i != j)
System.out.print(cplex.getValue(x[i][j]));
else
System.out.print("-");
}
}