OR-Tools  7.1
VrpResources.java
Go to the documentation of this file.
1 // Copyright 2010-2018 Google LLC
2 // Licensed under the Apache License, Version 2.0 (the "License");
3 // you may not use this file except in compliance with the License.
4 // You may obtain a copy of the License at
5 //
6 // http://www.apache.org/licenses/LICENSE-2.0
7 //
8 // Unless required by applicable law or agreed to in writing, software
9 // distributed under the License is distributed on an "AS IS" BASIS,
10 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11 // See the License for the specific language governing permissions and
12 // limitations under the License.
13 
14 // [START program]
15 // [START import]
26 import java.util.Arrays;
27 import java.util.logging.Logger;
28 // [END import]
29 
31 public class VrpResources {
32  static {
33  System.loadLibrary("jniortools");
34  }
35 
36  private static final Logger logger = Logger.getLogger(VrpResources.class.getName());
37 
38  // [START data_model]
39  static class DataModel {
40  public final long[][] timeMatrix = {
41  {0, 6, 9, 8, 7, 3, 6, 2, 3, 2, 6, 6, 4, 4, 5, 9, 7},
42  {6, 0, 8, 3, 2, 6, 8, 4, 8, 8, 13, 7, 5, 8, 12, 10, 14},
43  {9, 8, 0, 11, 10, 6, 3, 9, 5, 8, 4, 15, 14, 13, 9, 18, 9},
44  {8, 3, 11, 0, 1, 7, 10, 6, 10, 10, 14, 6, 7, 9, 14, 6, 16},
45  {7, 2, 10, 1, 0, 6, 9, 4, 8, 9, 13, 4, 6, 8, 12, 8, 14},
46  {3, 6, 6, 7, 6, 0, 2, 3, 2, 2, 7, 9, 7, 7, 6, 12, 8},
47  {6, 8, 3, 10, 9, 2, 0, 6, 2, 5, 4, 12, 10, 10, 6, 15, 5},
48  {2, 4, 9, 6, 4, 3, 6, 0, 4, 4, 8, 5, 4, 3, 7, 8, 10},
49  {3, 8, 5, 10, 8, 2, 2, 4, 0, 3, 4, 9, 8, 7, 3, 13, 6},
50  {2, 8, 8, 10, 9, 2, 5, 4, 3, 0, 4, 6, 5, 4, 3, 9, 5},
51  {6, 13, 4, 14, 13, 7, 4, 8, 4, 4, 0, 10, 9, 8, 4, 13, 4},
52  {6, 7, 15, 6, 4, 9, 12, 5, 9, 6, 10, 0, 1, 3, 7, 3, 10},
53  {4, 5, 14, 7, 6, 7, 10, 4, 8, 5, 9, 1, 0, 2, 6, 4, 8},
54  {4, 8, 13, 9, 8, 7, 10, 3, 7, 4, 8, 3, 2, 0, 4, 5, 6},
55  {5, 12, 9, 14, 12, 6, 6, 7, 3, 3, 4, 7, 6, 4, 0, 9, 2},
56  {9, 10, 18, 6, 8, 12, 15, 8, 13, 9, 13, 3, 4, 5, 9, 0, 9},
57  {7, 14, 9, 16, 14, 8, 5, 10, 6, 5, 4, 10, 8, 6, 2, 9, 0},
58  };
59  public final long[][] timeWindows = {
60  {0, 5}, // depot
61  {7, 12}, // 1
62  {10, 15}, // 2
63  {5, 14}, // 3
64  {5, 13}, // 4
65  {0, 5}, // 5
66  {5, 10}, // 6
67  {0, 10}, // 7
68  {5, 10}, // 8
69  {0, 5}, // 9
70  {10, 16}, // 10
71  {10, 15}, // 11
72  {0, 5}, // 12
73  {5, 10}, // 13
74  {7, 12}, // 14
75  {10, 15}, // 15
76  {5, 15}, // 16
77  };
78  public final int vehicleNumber = 4;
79  // [START resources_data]
80  public final int vehicleLoadTime = 5;
81  public final int vehicleUnloadTime = 5;
82  public final int depotCapacity = 2;
83  // [END resources_data]
84  public final int depot = 0;
85  }
86  // [END data_model]
87 
88  // [START solution_printer]
90  static void printSolution(
91  DataModel data, RoutingModel routing, RoutingIndexManager manager, Assignment solution) {
92  RoutingDimension timeDimension = routing.getMutableDimension("Time");
93  long totalTime = 0;
94  for (int i = 0; i < data.vehicleNumber; ++i) {
95  long index = routing.start(i);
96  logger.info("Route for Vehicle " + i + ":");
97  String route = "";
98  while (!routing.isEnd(index)) {
99  IntVar timeVar = timeDimension.cumulVar(index);
100  route += manager.indexToNode(index) + " Time(" + solution.min(timeVar) + ","
101  + solution.max(timeVar) + ") -> ";
102  index = solution.value(routing.nextVar(index));
103  }
104  IntVar timeVar = timeDimension.cumulVar(index);
105  route += manager.indexToNode(index) + " Time(" + solution.min(timeVar) + ","
106  + solution.max(timeVar) + ")";
107  logger.info(route);
108  logger.info("Time of the route: " + solution.min(timeVar) + "min");
109  totalTime += solution.min(timeVar);
110  }
111  logger.info("Total time of all routes: " + totalTime + "min");
112  }
113  // [END solution_printer]
114 
115  public static void main(String[] args) throws Exception {
116  // Instantiate the data problem.
117  // [START data]
118  final DataModel data = new DataModel();
119  // [END data]
120 
121  // Create Routing Index Manager
122  // [START index_manager]
123  RoutingIndexManager manager =
124  new RoutingIndexManager(data.timeMatrix.length, data.vehicleNumber, data.depot);
125  // [END index_manager]
126 
127  // Create Routing Model.
128  // [START routing_model]
129  RoutingModel routing = new RoutingModel(manager);
130  // [END routing_model]
131 
132  // Create and register a transit callback.
133  // [START transit_callback]
134  final int transitCallbackIndex =
135  routing.registerTransitCallback((long fromIndex, long toIndex) -> {
136  // Convert from routing variable Index to user NodeIndex.
137  int fromNode = manager.indexToNode(fromIndex);
138  int toNode = manager.indexToNode(toIndex);
139  return data.timeMatrix[fromNode][toNode];
140  });
141  // [END transit_callback]
142 
143  // Define cost of each arc.
144  // [START arc_cost]
145  routing.setArcCostEvaluatorOfAllVehicles(transitCallbackIndex);
146  // [END arc_cost]
147 
148  // Add Time constraint.
149  // [START time_constraint]
150  routing.addDimension(transitCallbackIndex, // transit callback
151  30, // allow waiting time
152  30, // vehicle maximum capacities
153  false, // start cumul to zero
154  "Time");
155  RoutingDimension timeDimension = routing.getMutableDimension("Time");
156  // Add time window constraints for each location except depot.
157  for (int i = 1; i < data.timeWindows.length; ++i) {
158  long index = manager.nodeToIndex(i);
159  timeDimension.cumulVar(index).setRange(data.timeWindows[i][0], data.timeWindows[i][1]);
160  }
161  // Add time window constraints for each vehicle start node.
162  for (int i = 0; i < data.vehicleNumber; ++i) {
163  long index = routing.start(i);
164  timeDimension.cumulVar(index).setRange(data.timeWindows[0][0], data.timeWindows[0][1]);
165  }
166  // [END time_constraint]
167 
168  // Add resource constraints at the depot.
169  // [START depot_load_time]
170  Solver solver = routing.solver();
171  IntervalVar[] intervals = new IntervalVar[data.vehicleNumber * 2];
172  for (int i = 0; i < data.vehicleNumber; ++i) {
173  // Add load duration at start of routes
174  intervals[2 * i] = solver.makeFixedDurationIntervalVar(
175  timeDimension.cumulVar(routing.start(i)), data.vehicleLoadTime, "depot_interval");
176  // Add unload duration at end of routes.
177  intervals[2 * i + 1] = solver.makeFixedDurationIntervalVar(
178  timeDimension.cumulVar(routing.end(i)), data.vehicleUnloadTime, "depot_interval");
179  }
180  // [END depot_load_time]
181 
182  // [START depot_capacity]
183  long[] depotUsage = new long[intervals.length];
184  Arrays.fill(depotUsage, 1);
185  solver.addConstraint(solver.makeCumulative(intervals, depotUsage, data.depotCapacity, "depot"));
186  // [END depot_capacity]
187 
188  // Instantiate route start and end times to produce feasible times.
189  // [START depot_start_end_times]
190  for (int i = 0; i < data.vehicleNumber; ++i) {
191  routing.addVariableMinimizedByFinalizer(timeDimension.cumulVar(routing.start(i)));
192  routing.addVariableMinimizedByFinalizer(timeDimension.cumulVar(routing.end(i)));
193  }
194  // [END depot_start_end_times]
195 
196  // Setting first solution heuristic.
197  // [START parameters]
198  RoutingSearchParameters searchParameters =
200  .toBuilder()
202  .build();
203  // [END parameters]
204 
205  // Solve the problem.
206  // [START solve]
207  Assignment solution = routing.solveWithParameters(searchParameters);
208  // [END solve]
209 
210  // Print solution on console.
211  // [START print_solution]
212  printSolution(data, routing, manager, solution);
213  // [END print_solution]
214  }
215 }
216 // [END program]
static void main(String[] args)
static com.google.ortools.constraintsolver.RoutingSearchParameters defaultRoutingSearchParameters()
RoutingDimension getMutableDimension(String dimension_name)
int registerTransitCallback(LongBinaryOperator callback)
.lang.Override com.google.ortools.constraintsolver.RoutingSearchParameters build()
Builder setFirstSolutionStrategy(com.google.ortools.constraintsolver.FirstSolutionStrategy.Value value)
Assignment solveWithParameters(com.google.ortools.constraintsolver.RoutingSearchParameters search_parameters)
void setArcCostEvaluatorOfAllVehicles(int evaluator_index)
Minimal VRP with Resource Constraints.
Constraint makeCumulative(IntervalVar[] intervals, long[] demands, long capacity, String name)
Definition: Solver.java:1377
IntervalVar makeFixedDurationIntervalVar(long start_min, long start_max, long duration, boolean optional, String name)
Definition: Solver.java:1282
boolean addDimension(int evaluator_index, long slack_max, long capacity, boolean fix_start_cumul_to_zero, String name)