我正在尝试将基本的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();
}
}