Google OR-Tools v9.15
a fast and portable software suite for combinatorial optimization
Loading...
Searching...
No Matches
vrp_resources.cc

Simple VRP example.

1// Copyright 2010-2025 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]
16#include <cstdint>
17#include <cstdlib>
18#include <sstream>
19#include <string>
20#include <utility>
21#include <vector>
22
29// [END import]
30
31namespace operations_research {
32// [START data_model]
33struct DataModel {
34 const std::vector<std::vector<int64_t>> time_matrix{
35 {0, 6, 9, 8, 7, 3, 6, 2, 3, 2, 6, 6, 4, 4, 5, 9, 7},
36 {6, 0, 8, 3, 2, 6, 8, 4, 8, 8, 13, 7, 5, 8, 12, 10, 14},
37 {9, 8, 0, 11, 10, 6, 3, 9, 5, 8, 4, 15, 14, 13, 9, 18, 9},
38 {8, 3, 11, 0, 1, 7, 10, 6, 10, 10, 14, 6, 7, 9, 14, 6, 16},
39 {7, 2, 10, 1, 0, 6, 9, 4, 8, 9, 13, 4, 6, 8, 12, 8, 14},
40 {3, 6, 6, 7, 6, 0, 2, 3, 2, 2, 7, 9, 7, 7, 6, 12, 8},
41 {6, 8, 3, 10, 9, 2, 0, 6, 2, 5, 4, 12, 10, 10, 6, 15, 5},
42 {2, 4, 9, 6, 4, 3, 6, 0, 4, 4, 8, 5, 4, 3, 7, 8, 10},
43 {3, 8, 5, 10, 8, 2, 2, 4, 0, 3, 4, 9, 8, 7, 3, 13, 6},
44 {2, 8, 8, 10, 9, 2, 5, 4, 3, 0, 4, 6, 5, 4, 3, 9, 5},
45 {6, 13, 4, 14, 13, 7, 4, 8, 4, 4, 0, 10, 9, 8, 4, 13, 4},
46 {6, 7, 15, 6, 4, 9, 12, 5, 9, 6, 10, 0, 1, 3, 7, 3, 10},
47 {4, 5, 14, 7, 6, 7, 10, 4, 8, 5, 9, 1, 0, 2, 6, 4, 8},
48 {4, 8, 13, 9, 8, 7, 10, 3, 7, 4, 8, 3, 2, 0, 4, 5, 6},
49 {5, 12, 9, 14, 12, 6, 6, 7, 3, 3, 4, 7, 6, 4, 0, 9, 2},
50 {9, 10, 18, 6, 8, 12, 15, 8, 13, 9, 13, 3, 4, 5, 9, 0, 9},
51 {7, 14, 9, 16, 14, 8, 5, 10, 6, 5, 4, 10, 8, 6, 2, 9, 0},
52 };
53 const std::vector<std::pair<int64_t, int64_t>> time_windows{
54 {0, 5}, // depot
55 {7, 12}, // 1
56 {10, 15}, // 2
57 {5, 14}, // 3
58 {5, 13}, // 4
59 {0, 5}, // 5
60 {5, 10}, // 6
61 {0, 10}, // 7
62 {5, 10}, // 8
63 {0, 5}, // 9
64 {10, 16}, // 10
65 {10, 15}, // 11
66 {0, 5}, // 12
67 {5, 10}, // 13
68 {7, 12}, // 14
69 {10, 15}, // 15
70 {5, 15}, // 16
71 };
72 const int num_vehicles = 4;
73 // [START resources_data]
74 const int vehicle_load_time = 5;
75 const int vehicle_unload_time = 5;
76 const int depot_capacity = 2;
77 // [END resources_data]
78 const RoutingIndexManager::NodeIndex depot{0};
79};
80// [END data_model]
81
82// [START solution_printer]
88void PrintSolution(const DataModel& data, const RoutingIndexManager& manager,
89 const RoutingModel& routing, const Assignment& solution) {
90 const RoutingDimension& time_dimension = routing.GetDimensionOrDie("Time");
91 int64_t total_time{0};
92 for (int vehicle_id = 0; vehicle_id < data.num_vehicles; ++vehicle_id) {
93 if (!routing.IsVehicleUsed(solution, vehicle_id)) {
94 continue;
95 }
96 int64_t index = routing.Start(vehicle_id);
97 LOG(INFO) << "Route for vehicle " << vehicle_id << ":";
98 std::ostringstream route;
99 while (!routing.IsEnd(index)) {
100 auto time_var = time_dimension.CumulVar(index);
101 route << manager.IndexToNode(index).value() << " Time("
102 << solution.Min(time_var) << ", " << solution.Max(time_var)
103 << ") -> ";
104 index = solution.Value(routing.NextVar(index));
105 }
106 auto time_var = time_dimension.CumulVar(index);
107 LOG(INFO) << route.str() << manager.IndexToNode(index).value() << " Time("
108 << solution.Min(time_var) << ", " << solution.Max(time_var)
109 << ")";
110 LOG(INFO) << "Time of the route: " << solution.Min(time_var) << "min";
111 total_time += solution.Min(time_var);
112 }
113 LOG(INFO) << "Total time of all routes: " << total_time << "min";
114 LOG(INFO) << "";
115 LOG(INFO) << "Advanced usage:";
116 LOG(INFO) << "Problem solved in " << routing.solver()->wall_time() << "ms";
117}
118// [END solution_printer]
119
120void VrpTimeWindows() {
121 // Instantiate the data problem.
122 // [START data]
123 DataModel data;
124 // [END data]
125
126 // Create Routing Index Manager
127 // [START index_manager]
128 RoutingIndexManager manager(data.time_matrix.size(), data.num_vehicles,
129 data.depot);
130 // [END index_manager]
131
132 // Create Routing Model.
133 // [START routing_model]
134 RoutingModel routing(manager);
135 // [END routing_model]
136
137 // Create and register a transit callback.
138 // [START transit_callback]
139 const int transit_callback_index = routing.RegisterTransitCallback(
140 [&data, &manager](const int64_t from_index,
141 const int64_t to_index) -> int64_t {
142 // Convert from routing variable Index to time matrix NodeIndex.
143 const int from_node = manager.IndexToNode(from_index).value();
144 const int to_node = manager.IndexToNode(to_index).value();
145 return data.time_matrix[from_node][to_node];
146 });
147 // [END transit_callback]
148
149 // Define cost of each arc.
150 // [START arc_cost]
151 routing.SetArcCostEvaluatorOfAllVehicles(transit_callback_index);
152 // [END arc_cost]
153
154 // Add Time constraint.
155 // [START time_constraint]
156 const std::string time = "Time";
157 routing.AddDimension(transit_callback_index, // transit callback index
158 int64_t{30}, // allow waiting time
159 int64_t{30}, // maximum time per vehicle
160 false, // Don't force start cumul to zero
161 time);
162 const RoutingDimension& time_dimension = routing.GetDimensionOrDie(time);
163 // Add time window constraints for each location except depot.
164 for (int i = 1; i < data.time_windows.size(); ++i) {
165 const int64_t index =
166 manager.NodeToIndex(RoutingIndexManager::NodeIndex(i));
167 time_dimension.CumulVar(index)->SetRange(data.time_windows[i].first,
168 data.time_windows[i].second);
169 }
170 // Add time window constraints for each vehicle start node.
171 for (int i = 0; i < data.num_vehicles; ++i) {
172 const int64_t index = routing.Start(i);
173 time_dimension.CumulVar(index)->SetRange(data.time_windows[0].first,
174 data.time_windows[0].second);
175 }
176 // [END time_constraint]
177
178 // Add resource constraints at the depot.
179 // [START depot_load_time]
180 Solver* solver = routing.solver();
181 std::vector<IntervalVar*> intervals;
182 for (int i = 0; i < data.num_vehicles; ++i) {
183 // Add load duration at start of routes
184 intervals.push_back(solver->MakeFixedDurationIntervalVar(
185 time_dimension.CumulVar(routing.Start(i)), data.vehicle_load_time,
186 "depot_interval"));
187 // Add unload duration at end of routes.
188 intervals.push_back(solver->MakeFixedDurationIntervalVar(
189 time_dimension.CumulVar(routing.End(i)), data.vehicle_unload_time,
190 "depot_interval"));
191 }
192 // [END depot_load_time]
193
194 // [START depot_capacity]
195 std::vector<int64_t> depot_usage(intervals.size(), 1);
196 solver->AddConstraint(solver->MakeCumulative(intervals, depot_usage,
197 data.depot_capacity, "depot"));
198 // [END depot_capacity]
199
200 // Instantiate route start and end times to produce feasible times.
201 // [START depot_start_end_times]
202 for (int i = 0; i < data.num_vehicles; ++i) {
203 routing.AddVariableMinimizedByFinalizer(
204 time_dimension.CumulVar(routing.Start(i)));
205 routing.AddVariableMinimizedByFinalizer(
206 time_dimension.CumulVar(routing.End(i)));
207 }
208 // [END depot_start_end_times]
209
210 // Setting first solution heuristic.
211 // [START parameters]
212 RoutingSearchParameters searchParameters = DefaultRoutingSearchParameters();
213 searchParameters.set_first_solution_strategy(
215 // [END parameters]
216
217 // Solve the problem.
218 // [START solve]
219 const Assignment* solution = routing.SolveWithParameters(searchParameters);
220 // [END solve]
221
222 // Print solution on console.
223 // [START print_solution]
224 PrintSolution(data, manager, routing, *solution);
225 // [END print_solution]
226}
227} // namespace operations_research
228
229int main(int /*argc*/, char* /*argv*/[]) {
230 operations_research::VrpTimeWindows();
231 return EXIT_SUCCESS;
232}
233// [END program]
int main(int argc, char **argv)
Definition fz.cc:218
OR-Tools root namespace.
Select next search node to expand Select next item_i to add this new search node to the search Generate a new search node where item_i is not in the knapsack Check validity of this new partial solution(using propagators) - If valid
RoutingSearchParameters DefaultRoutingSearchParameters()
The vehicle routing library lets one model and solve generic vehicle routing problems ranging from th...