Переписывание модели OPL на Java - PullRequest
0 голосов
/ 05 сентября 2018

Я пытаюсь переписать базовую модель VRPTW с OPL на Java. Когда я запускаю его в OPL, в результате я получаю объективное значение 290,1, но при запуске кода Java результат равен 189,5 с теми же входными данными. Я не уверен, что я просто сделал какую-то ошибку в процессе переписывания. Любые идеи приветствуются ...

Я приложил Изображения модели OPL, и вот код, написанный на Java: пакет OPLModel;

public static void main(String[] args) {
    // TODO Auto-generated method stub

    int n = 17; //number of customers
    int v = 5; //number of vehicles
    double M = 1000; //big M
    float[] Xcoord = {35, 35, 41, 35, 55, 15, 25, 20, 10, 55, 30, 20, 50, 30, 15, 30, 35};
    float[] Ycoord = {35, 49, 17, 45, 20, 30, 30, 50, 43, 60, 60, 65, 35, 25, 10, 5, 35}; 
    float[] s = {0, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 0}; //service time
    double[] e = {0, 60, 60, 120, 120, 180, 180, 180, 240, 240 ,240, 300, 300, 300, 360, 360,  0}; //earliest delivery time
    double[] l = {480, 120, 180, 180, 240, 300, 300, 360, 420, 300, 360, 360, 420, 450, 450, 450, 480}; //latest delivery time
    float[] w = {0, 10, 7, 13, 19, 26, 3, 5, 9, 16, 16, 12, 19, 23, 20, 8, 0}; //order weight
    float Q = 200; //volume capacity of vehicle 

     // Euclidean distances 
    double[][] d = new double[n][n];
    for(int i = 0; i < n; i++) {
        for(int j = 0; j < n; j++) {
            if (i==j) {
                d[i][j]=0;
            }else {
            d[i][j] = Math.sqrt(Math.pow(Xcoord[i] - Ycoord[j], 2) + Math.pow(Xcoord[i] - Ycoord[j], 2));
            }
        }
    }
    //Time between i and j
    double[][] t = new double[n][n];
    for(int i = 0; i < n; i++) {
        for(int j = 0; j < n; j++) {
            if (i==j) {
                t[i][j]=0;
            }else {
            t[i][j] = d[i][j]+ s[i];
            }
        }
    }
    try {

        //model def
        IloCplex cplex = new IloCplex();

        //variables def
        IloIntVar [][][] x = new IloIntVar [n][][]; 
            for (int i = 0; i < n; i++) {
                x[i] = new IloIntVar [n][];
                for (int j = 0; j < n; j++) {
                    x[i][j] = cplex.boolVarArray(v); 
                }
            }
        //arrival time of vehicle k at customer i
        IloNumVar [][]a = new IloNumVar [n][];
            for(int i = 0; i < n; i++) {
                a[i] =cplex.numVarArray(v, 0, Double.MAX_VALUE);
        } 
        //Objective Expression
            IloLinearNumExpr objective = cplex.linearNumExpr();
            for (int i = 0; i < n; i++) {
                for (int j = 0; j < n; j++) {
                    for (int k = 0; k < v; k++) {
                        objective.addTerm(d[i][j], x[i][j][k]);
                        }
                    }
                }
        //Define objective
            cplex.addMinimize(objective);

        //Define constraints

        // constraint 0: Eliminate i to i nodes
            for(int i = 0; i < n; i++) {
                for(int k = 0; k < v; k++) {
                    IloLinearNumExpr expr0 = cplex.linearNumExpr();
                    expr0.addTerm(1.0, x[i][i][k]);
                    cplex.addEq(expr0, 0);
                }
            }
        // constraint 1: Each customer is visited only once
            for(int i = 1; i < n-1; i++) {  
                IloLinearNumExpr expr1 = cplex.linearNumExpr();
                    for(int j = 0; j < n; j++) {
                        for(int k = 0; k < v; k++) {
                            if(i != j) {

                                expr1.addTerm(1.0, x[i][j][k]);
                            }
                        }
                    }       
                    cplex.addEq(expr1, 1.0);
            }

        //Constraint 2: vehicle capacity constraint

        for(int k = 0; k < v; k++) {
            IloLinearNumExpr expr2 = cplex.linearNumExpr();
                for(int i = 1; i < n-1; i++) {
                    for(int j = 0; j < n; j++) {
                    if(i != j) {
                            expr2.addTerm(w[i], x[i][j][k]);
                        }
                    }
                }
                cplex.addLe(expr2, Q);
            }

        //Constraint 3: Each vehicle must start from depot 0

            for(int k = 0; k < v; k++) {
                IloLinearNumExpr expr3 = cplex.linearNumExpr();
                    for(int j = 0; j < n; j++) {
                        expr3.addTerm(1.0, x[0][j][k]);
                    }
                    cplex.addEq(expr3, 1.0);
            }

        //constraint 4: after arriving to customer vehicle must leave for next
            for(int h = 1; h < n-1; h++) {
                for(int k = 0; k < v; k++) {
                    IloLinearNumExpr expr4 = cplex.linearNumExpr();
                        for(int i = 0; i < n; i++) {
                            for(int j = 0; j < n; j++) {
                                if(i != j) {
                                    expr4.addTerm(1.0, x[i][h][k]);
                                    expr4.addTerm(-1.0, x[h][j][k]);
                                }
                            }
                        }
                        cplex.addEq(expr4, 0);
                }
            }

        //Constraint 5: Each vehicle must end in depot n

            for(int k = 0; k < v; k++) {
                IloLinearNumExpr expr5 = cplex.linearNumExpr();
                    for(int i = 0; i < n; i++) {
                        expr5.addTerm(1.0, x[i][n-1][k]);

                    }
                    cplex.addEq(expr5, 1.0);
            }


        //constraint 6: time window-earliest arrival time
            for(int i = 0; i < n; i++) {
                for(int k = 0; k < v; k++) {
                    IloLinearNumExpr expr6 = cplex.linearNumExpr();
                                expr6.addTerm(1.0, a[i][k]);
                                cplex.addGe(expr6, e[i]);
                }   
            }

            //costraint 7: time window-latest arrival time
            for(int i = 0; i < n; i++) {
                for(int k = 0; k < v; k++) {
                    IloLinearNumExpr expr7 = cplex.linearNumExpr();
                                expr7.addTerm(1.0, a[i][k]);
                                cplex.addLe(expr7, l[i]);
                }   
            }

        //constraint 8: time
                for(int i = 0; i < n; i++) {
                    for(int j = 0; j < n; j++) {
                        for(int k = 0; k < v; k++) {
                            if(i != j) {
                                IloLinearNumExpr expr8 = cplex.linearNumExpr();
                                expr8.addTerm(1.0, a[i][k]);
                                expr8.setConstant(t[i][j]);
                                expr8.addTerm(-1.0, a[j][k]);
                                expr8.addTerm(M, x[i][j][k]);
                                cplex.addLe(expr8, M);
                            } 
                        }
                    }
                }
    // solve model
       if (cplex.solve()) {
        System.out.println("obj = "+cplex.getObjValue());

       }
          else {
              System.out.println("problem not solved");
          }

       cplex.end();
    }
    catch (IloException exc) {
        exc.printStackTrace();
    }
}

OPL Model1

Модель OPL

...