3

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

cplex解決が完了したら、次のような値を取得したいと思いますx

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

しかし、それはエラーを出します。アドバイスをいただける方に感謝します。エラーは次のとおりです。

 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();    
}
}
4

1 に答える 1

3

IBM ナレッジ センターのこのページを見ると、ここgetValue()の例のように、 への引数は、解決しようとしているモデルを構築するために使用されたものでなければなりません。であるため、おそらくとして初期化する必要があります。を呼び出す前のある時点で、 の要素をモデルに追加する必要があります。varn x nxIloNumVar[][] x = new IloNumVar[n][n];solve()x

セットアップでは、 の対角要素がxモデルによって参照されることはありません。すべてのセットアップ ループに条件があることに気付くでしょうif(i != j)else問題を解決するには、ループの少なくとも 1 つに句を追加するか、それが意味をなさない場合 (私が疑うように)、入力と一貫して出力を行います。

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("-");
    }   
}
于 2016-01-29T03:32:47.303 に答える