30
30
import java .util .function .LongUnaryOperator ;
31
31
import java .util .logging .Logger ;
32
32
33
- // A pair class
34
- class Pair <K , V > {
35
- final K first ;
36
- final V second ;
37
-
38
- public static <K , V > Pair <K , V > of (K element0 , V element1 ) {
39
- return new Pair <K , V >(element0 , element1 );
40
- }
41
-
42
- public Pair (K element0 , V element1 ) {
43
- this .first = element0 ;
44
- this .second = element1 ;
45
- }
46
- }
47
-
48
33
/**
49
34
* Sample showing how to model and solve a capacitated vehicle routing problem with time windows
50
35
* using the swig-wrapped version of the vehicle routing library in
@@ -54,82 +39,97 @@ public class CapacitatedVehicleRoutingProblemWithTimeWindows {
54
39
private static final Logger logger =
55
40
Logger .getLogger (CapacitatedVehicleRoutingProblemWithTimeWindows .class .getName ());
56
41
42
+ // A pair class
43
+ static class Pair <K , V > {
44
+ final K first ;
45
+ final V second ;
46
+
47
+ public static <K , V > Pair <K , V > of (K element0 , V element1 ) {
48
+ return new Pair <K , V >(element0 , element1 );
49
+ }
50
+
51
+ public Pair (K element0 , V element1 ) {
52
+ this .first = element0 ;
53
+ this .second = element1 ;
54
+ }
55
+ }
56
+
57
57
static class DataModel {
58
- // Locations representing either an order location or a vehicle route
59
- // start/end.
58
+ // Locations representing either an order location or a vehicle route
59
+ // start/end.
60
60
public final List <Pair <Integer , Integer >> locations = new ArrayList <>();
61
61
62
- // Quantity to be picked up for each order.
62
+ // Quantity to be picked up for each order.
63
63
public final List <Integer > orderDemands = new ArrayList <>();
64
- // Time window in which each order must be performed.
64
+ // Time window in which each order must be performed.
65
65
public final List <Pair <Integer , Integer >> orderTimeWindows = new ArrayList <>();
66
- // Penalty cost "paid" for dropping an order.
66
+ // Penalty cost "paid" for dropping an order.
67
67
public final List <Integer > orderPenalties = new ArrayList <>();
68
68
69
69
public final int numberOfVehicles = 20 ;
70
70
71
- // Capacity of the vehicles.
71
+ // Capacity of the vehicles.
72
72
public final int vehicleCapacity = 50 ;
73
73
public final int numberOfOrders = 100 ;
74
- // Latest time at which each vehicle must end its tour.
74
+ // Latest time at which each vehicle must end its tour.
75
75
public final List <Integer > vehicleEndTime = new ArrayList <>();
76
- // Cost per unit of distance of each vehicle.
76
+ // Cost per unit of distance of each vehicle.
77
77
public final List <Integer > vehicleCostCoefficients = new ArrayList <>();
78
- // Vehicle start and end indices. They have to be implemented as int[] due
79
- // to the available SWIG-ed interface.
78
+ // Vehicle start and end indices. They have to be implemented as int[] due
79
+ // to the available SWIG-ed interface.
80
80
public int [] vehicleStarts ;
81
81
public int [] vehicleEnds ;
82
82
83
- // Random number generator to produce data.
84
- private final Random randomGenerator = new Random (0xBEEF );
83
+ // Random number generator to produce data.
84
+ private final Random randomGenerator = new Random (0xBEEF );
85
85
86
- /**
86
+ /**
87
87
* Creates order data. Location of the order is random, as well as its demand (quantity), time
88
88
* window and penalty.
89
- *
90
- * @param xMax maximum x coordinate in which orders are located.
91
- * @param yMax maximum y coordinate in which orders are located.
92
- * @param demandMax maximum quantity of a demand.
93
- * @param timeWindowMax maximum starting time of the order time window.
94
- * @param timeWindowWidth duration of the order time window.
95
- * @param penaltyMin minimum pernalty cost if order is dropped.
96
- * @param penaltyMax maximum pernalty cost if order is dropped.
97
- */
89
+ *
90
+ * @param xMax maximum x coordinate in which orders are located.
91
+ * @param yMax maximum y coordinate in which orders are located.
92
+ * @param demandMax maximum quantity of a demand.
93
+ * @param timeWindowMax maximum starting time of the order time window.
94
+ * @param timeWindowWidth duration of the order time window.
95
+ * @param penaltyMin minimum pernalty cost if order is dropped.
96
+ * @param penaltyMax maximum pernalty cost if order is dropped.
97
+ */
98
98
private void buildOrders (int xMax , int yMax , int demandMax , int timeWindowMax ,
99
99
int timeWindowWidth , int penaltyMin , int penaltyMax ) {
100
- for (int order = 0 ; order < numberOfOrders ; ++order ) {
100
+ for (int order = 0 ; order < numberOfOrders ; ++order ) {
101
101
locations .add (
102
102
Pair .of (randomGenerator .nextInt (xMax + 1 ), randomGenerator .nextInt (yMax + 1 )));
103
- orderDemands .add (randomGenerator .nextInt (demandMax + 1 ));
104
- int timeWindowStart = randomGenerator .nextInt (timeWindowMax + 1 );
105
- orderTimeWindows .add (Pair .of (timeWindowStart , timeWindowStart + timeWindowWidth ));
106
- orderPenalties .add (randomGenerator .nextInt (penaltyMax - penaltyMin + 1 ) + penaltyMin );
103
+ orderDemands .add (randomGenerator .nextInt (demandMax + 1 ));
104
+ int timeWindowStart = randomGenerator .nextInt (timeWindowMax + 1 );
105
+ orderTimeWindows .add (Pair .of (timeWindowStart , timeWindowStart + timeWindowWidth ));
106
+ orderPenalties .add (randomGenerator .nextInt (penaltyMax - penaltyMin + 1 ) + penaltyMin );
107
+ }
107
108
}
108
- }
109
109
110
- /**
110
+ /**
111
111
* Creates fleet data. Vehicle starting and ending locations are random, as well as vehicle
112
112
* costs per distance unit.
113
- *
114
- * @param xMax maximum x coordinate in which orders are located.
115
- * @param yMax maximum y coordinate in which orders are located.
116
- * @param endTime latest end time of a tour of a vehicle.
113
+ *
114
+ * @param xMax maximum x coordinate in which orders are located.
115
+ * @param yMax maximum y coordinate in which orders are located.
116
+ * @param endTime latest end time of a tour of a vehicle.
117
117
* @param costCoefficientMax maximum cost per distance unit of a vehicle (minimum is 1),
118
- */
118
+ */
119
119
private void buildFleet (int xMax , int yMax , int endTime , int costCoefficientMax ) {
120
- vehicleStarts = new int [numberOfVehicles ];
121
- vehicleEnds = new int [numberOfVehicles ];
122
- for (int vehicle = 0 ; vehicle < numberOfVehicles ; ++vehicle ) {
123
- vehicleStarts [vehicle ] = locations .size ();
120
+ vehicleStarts = new int [numberOfVehicles ];
121
+ vehicleEnds = new int [numberOfVehicles ];
122
+ for (int vehicle = 0 ; vehicle < numberOfVehicles ; ++vehicle ) {
123
+ vehicleStarts [vehicle ] = locations .size ();
124
124
locations .add (
125
125
Pair .of (randomGenerator .nextInt (xMax + 1 ), randomGenerator .nextInt (yMax + 1 )));
126
- vehicleEnds [vehicle ] = locations .size ();
126
+ vehicleEnds [vehicle ] = locations .size ();
127
127
locations .add (
128
128
Pair .of (randomGenerator .nextInt (xMax + 1 ), randomGenerator .nextInt (yMax + 1 )));
129
- vehicleEndTime .add (endTime );
130
- vehicleCostCoefficients .add (randomGenerator .nextInt (costCoefficientMax ) + 1 );
129
+ vehicleEndTime .add (endTime );
130
+ vehicleCostCoefficients .add (randomGenerator .nextInt (costCoefficientMax ) + 1 );
131
+ }
131
132
}
132
- }
133
133
134
134
public DataModel () {
135
135
final int xMax = 20 ;
@@ -174,7 +174,7 @@ public long applyAsLong(long fromIndex, long toIndex) {
174
174
};
175
175
}
176
176
177
- /// @brief Print the solution.
177
+ // Print the solution.
178
178
static void printSolution (
179
179
DataModel data , RoutingModel model , RoutingIndexManager manager , Assignment solution ) {
180
180
RoutingSearchStatus .Value status = model .status ();
@@ -184,7 +184,6 @@ static void printSolution(
184
184
logger .warning ("No solution found!" );
185
185
return ;
186
186
}
187
- String output = "" ;
188
187
189
188
// Solution cost.
190
189
logger .info ("Objective : " + solution .objectiveValue ());
@@ -196,7 +195,7 @@ static void printSolution(
196
195
}
197
196
}
198
197
if (dropped .length () > 0 ) {
199
- output += "Dropped orders:" + dropped + " \n " ;
198
+ logger . info ( "Dropped orders:" + dropped ) ;
200
199
}
201
200
202
201
// Routes
@@ -221,12 +220,12 @@ static void printSolution(
221
220
IntVar time = timeDimension .cumulVar (index );
222
221
long nodeIndex = manager .indexToNode (index );
223
222
route += nodeIndex + " Load(" + solution .value (load ) + ")" ;
224
- route += " Time(" + solution .min (time ) + ", " + solution .max (time ) + ") -> " ;
223
+ route += " Time(" + solution .min (time ) + ", " + solution .max (time ) + ")" ;
225
224
logger .info (route );
226
225
}
227
226
}
228
227
229
- public static void main (String [] args ) throws Exception {
228
+ public static void main (String [] args ) {
230
229
Loader .loadNativeLibraries ();
231
230
232
231
// Instantiate the data problem.
@@ -261,7 +260,6 @@ public long applyAsLong(long fromIndex) {
261
260
};
262
261
unused = model .addDimension (model .registerUnaryTransitCallback (demandCallback ), 0 ,
263
262
data .vehicleCapacity , true , "capacity" );
264
- RoutingDimension capacityDimension = model .getMutableDimension ("capacity" );
265
263
266
264
// Setting up vehicles
267
265
LongBinaryOperator [] callbacks = new LongBinaryOperator [data .numberOfVehicles ];
@@ -293,4 +291,6 @@ public long applyAsLong(long fromIndex) {
293
291
// Print solution on console.
294
292
printSolution (data , model , manager , solution );
295
293
}
294
+
295
+ private CapacitatedVehicleRoutingProblemWithTimeWindows () {}
296
296
}
0 commit comments