3

I use cplex to solve the travelling salesman problem (TSP). Given that if x[i][j]=1, then the path goes from the city i to the city j, otherwise, ther is no path between these cities. The corresponding matrix:

IloNumVar[][] x = new IloNumVar[n][];
for(int i = 0; i < n; i++){
    x[i] = cplex.boolVarArray(n);
}

When cplex finishes solving, I want to get the values of x like this:

if(cplex.solve()){
    double[][] var = new double[n][n];
    for(int i = 0; i<x.length; i++){
        for(int j = 0 ; j < x[i].length; j ++){
            var[i][j] = cplex.getValue(x[i][j]);
            if(var[i][j] ==1){
                System.out.print(i + "  "+ j);
            }       
        }   
    }
}

but it gives an error. I will appreciate anyone who can give some advice. the error is in :

 var[i][j] = cplex.getValue(x[i][j]);

the explain is :

Exception in thread "main"  ilog.cplex.IloCplex$UnknownObjectException: CPLEX Error: object is unknown to IloCplex
at ilog.cplex.IloCplex.getValue(IloCplex.java:6495)

the entire code is following:

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();    
}
}
SnareChops
  • 13,175
  • 9
  • 69
  • 91
Joyee
  • 31
  • 1
  • 4
  • "Tell us what the exact wording of the error message is" (taken from "how to ask" help: http://stackoverflow.com/help/mcve) – John_West Jan 28 '16 at 13:33
  • Post the code that initializes `x` and add it to the model. That is what is really causing the error. – Mad Physicist Jan 29 '16 at 03:34
  • What do you do to `x` to associate it with `cplx`? You should really post a complete minimal example that we can run ourselves to reproduce the error. – Mad Physicist Jan 29 '16 at 04:19
  • @Mad Physicist I really appreciate you can share time to run this. – Joyee Jan 29 '16 at 11:42
  • @Joyee. I did not get a chance to run the code but I do see a major issue that I think will fix your problem. The answer has been updated. – Mad Physicist Jan 29 '16 at 14:22
  • I appreciate the fact that you responded to our requests for more information. It is refreshing to see someone actually trying to get help with a problem instead of just dumping their crap here out of sheer laziness. – Mad Physicist Jan 31 '16 at 05:04

1 Answers1

3

Looking at this page at the IBM knowledge center, the argument to getValue() must be something that was used to construct the model you are solving, as in the example here. Since var is n x n, you should probably initialize x as IloNumVar[][] x = new IloNumVar[n][n];. At some point before calling solve(), each element of x should be added to your model.

In your setup, the diagonal elements of x are never referenced by the model. You will notice that all your setup loops have a condition if(i != j). To fix your issue, either add an else clause to at least one of the loops, or if that is meaningless (as I suspect it is), do your printout consistently with the input:

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("-");
    }   
}
Mad Physicist
  • 107,652
  • 25
  • 181
  • 264
  • Thank you first.I have added x to my model: `IloNumVar[][] x = new IloNumVar[n][]; for(int i = 0; i < n; i++){ x[i] = cplex.boolVarArray(n); }` If I don't getValues of variables .It can solve . – Joyee Jan 29 '16 at 04:13
  • 2
    Just creating the variables is not necessarily enough for them to get extracted into CPLEX. Only the variables that actually appear in either a constraint or the objective will get extracted into CPLEX. So, depending on how you build your model, there may not be any constraint that includes some of the variables you have created. Does it fall over on the first time round the loop? Is there a constraint that says anything about x[0][0]? – TimChippingtonDerrick Jan 29 '16 at 09:34
  • @TimChippingtonDerrick. You are right. With the posted code, the omission is pretty glaring. – Mad Physicist Jan 29 '16 at 14:21
  • @TimChippingtonDerrick You are right. I have fixed the problem.Thank you – Joyee Jan 30 '16 at 05:37
  • @MadPhysicist.Thank you – Joyee Jan 30 '16 at 05:37