Skip to content

Commit 6a1a8ce

Browse files
committed
routing: improve doxygen
1 parent bc4f4ec commit 6a1a8ce

File tree

2 files changed

+171
-157
lines changed

2 files changed

+171
-157
lines changed

ortools/constraint_solver/routing.h

Lines changed: 140 additions & 146 deletions
Original file line numberDiff line numberDiff line change
@@ -11,147 +11,143 @@
1111
// See the License for the specific language governing permissions and
1212
// limitations under the License.
1313

14-
/// The vehicle routing library lets one model and solve generic vehicle routing
15-
/// problems ranging from the Traveling Salesman Problem to more complex
16-
/// problems such as the Capacitated Vehicle Routing Problem with Time Windows.
17-
///
18-
/// The objective of a vehicle routing problem is to build routes covering a set
19-
/// of nodes minimizing the overall cost of the routes (usually proportional to
20-
/// the sum of the lengths of each segment of the routes) while respecting some
21-
/// problem-specific constraints (such as the length of a route). A route is
22-
/// equivalent to a path connecting nodes, starting/ending at specific
23-
/// starting/ending nodes.
24-
///
25-
/// The term "vehicle routing" is historical and the category of problems solved
26-
/// is not limited to the routing of vehicles: any problem involving finding
27-
/// routes visiting a given number of nodes optimally falls under this category
28-
/// of problems, such as finding the optimal sequence in a playlist.
29-
/// The literature around vehicle routing problems is extremely dense but one
30-
/// can find some basic introductions in the following links:
31-
/// - http://en.wikipedia.org/wiki/Travelling_salesman_problem
32-
/// - http://en.wikipedia.org/wiki/Vehicle_routing_problem
33-
///
34-
/// The vehicle routing library is a vertical layer above the constraint
35-
/// programming library (ortools/constraint_programming:cp).
36-
/// One has access to all underlying constrained variables of the vehicle
37-
/// routing model which can therefore be enriched by adding any constraint
38-
/// available in the constraint programming library.
39-
///
40-
/// There are two sets of variables available:
41-
/// - path variables:
42-
/// * "next(i)" variables representing the immediate successor of the node
43-
/// corresponding to i; use IndexToNode() to get the node corresponding to
44-
/// a "next" variable value; note that node indices are strongly typed
45-
/// integers (cf. ortools/base/int_type.h);
46-
/// * "vehicle(i)" variables representing the vehicle route to which the
47-
/// node corresponding to i belongs;
48-
/// * "active(i)" boolean variables, true if the node corresponding to i is
49-
/// visited and false if not; this can be false when nodes are either
50-
/// optional or part of a disjunction;
51-
/// * The following relationships hold for all i:
52-
/// active(i) == 0 <=> next(i) == i <=> vehicle(i) == -1,
53-
/// next(i) == j => vehicle(j) == vehicle(i).
54-
/// - dimension variables, used when one is accumulating quantities along
55-
/// routes, such as weight or volume carried, distance or time:
56-
/// * "cumul(i,d)" variables representing the quantity of dimension d when
57-
/// arriving at the node corresponding to i;
58-
/// * "transit(i,d)" variables representing the quantity of dimension d added
59-
/// after visiting the node corresponding to i.
60-
/// * The following relationship holds for all (i,d):
61-
/// next(i) == j => cumul(j,d) == cumul(i,d) + transit(i,d).
62-
/// Solving the vehicle routing problems is mainly done using approximate
63-
/// methods (namely local search,
64-
/// cf. http://en.wikipedia.org/wiki/Local_search_(optimization) ), potentially
65-
/// combined with exact techniques based on dynamic programming and exhaustive
66-
/// tree search.
67-
// TODO(user): Add a section on costs (vehicle arc costs, span costs,
68-
// disjunctions costs).
69-
//
70-
/// Advanced tips: Flags are available to tune the search used to solve routing
71-
/// problems. Here is a quick overview of the ones one might want to modify:
72-
/// - Limiting the search for solutions:
73-
/// * routing_solution_limit (default: kint64max): stop the search after
74-
/// finding 'routing_solution_limit' improving solutions;
75-
/// * routing_time_limit (default: kint64max): stop the search after
76-
/// 'routing_time_limit' milliseconds;
77-
/// - Customizing search:
78-
/// * routing_first_solution (default: select the first node with an unbound
79-
/// successor and connect it to the first available node): selects the
80-
/// heuristic to build a first solution which will then be improved by local
81-
/// search; possible values are GlobalCheapestArc (iteratively connect two
82-
/// nodes which produce the cheapest route segment), LocalCheapestArc
83-
/// (select the first node with an unbound successor and connect it to the
84-
/// node which produces the cheapest route segment), PathCheapestArc
85-
/// (starting from a route "start" node, connect it to the node which
86-
/// produces the cheapest route segment, then extend the route by iterating
87-
/// on the last node added to the route).
88-
/// * Local search neighborhoods:
89-
/// - routing_no_lns (default: false): forbids the use of Large Neighborhood
90-
/// Search (LNS); LNS can find good solutions but is usually very slow.
91-
/// Refer to the description of PATHLNS in the LocalSearchOperators enum
92-
/// in constraint_solver.h for more information.
93-
/// - routing_no_tsp (default: true): forbids the use of exact methods to
94-
/// solve "sub"-traveling salesman problems (TSPs) of the current model
95-
/// (such as sub-parts of a route, or one route in a multiple route
96-
/// problem). Uses dynamic programming to solve such TSPs with a maximum
97-
/// size (in number of nodes) up to cp_local_search_tsp_opt_size (flag
98-
/// with a default value of 13 nodes). It is not activated by default
99-
/// because it can slow down the search.
100-
/// * Meta-heuristics: used to guide the search out of local minima found by
101-
/// local search. Note that, in general, a search with metaheuristics
102-
/// activated never stops, therefore one must specify a search limit.
103-
/// Several types of metaheuristics are provided:
104-
/// - routing_guided_local_search (default: false): activates guided local
105-
/// search (cf. http://en.wikipedia.org/wiki/Guided_Local_Search);
106-
/// this is generally the most efficient metaheuristic for vehicle
107-
/// routing;
108-
/// - routing_simulated_annealing (default: false): activates simulated
109-
/// annealing (cf. http://en.wikipedia.org/wiki/Simulated_annealing);
110-
/// - routing_tabu_search (default: false): activates tabu search (cf.
111-
/// http://en.wikipedia.org/wiki/Tabu_search).
112-
///
113-
/// Code sample:
114-
/// Here is a simple example solving a traveling salesman problem given a cost
115-
/// function callback (returns the cost of a route segment):
116-
///
117-
/// - Define a custom distance/cost function from an index to another; in this
118-
/// example just returns the sum of the indices:
119-
///
120-
/// int64_t MyDistance(int64_t from, int64_t to) {
121-
/// return from + to;
122-
/// }
123-
///
124-
/// - Create a routing model for a given problem size (int number of nodes) and
125-
/// number of routes (here, 1):
126-
///
127-
/// RoutingIndexManager manager(...number of nodes..., 1);
128-
/// RoutingModel routing(manager);
129-
///
130-
/// - Set the cost function by registering an std::function<int64_t(int64_t,
131-
/// int64_t)> in the model and passing its index as the vehicle cost.
132-
///
133-
/// const int cost = routing.RegisterTransitCallback(MyDistance);
134-
/// routing.SetArcCostEvaluatorOfAllVehicles(cost);
135-
///
136-
/// - Find a solution using Solve(), returns a solution if any (owned by
137-
/// routing):
138-
///
139-
/// const Assignment* solution = routing.Solve();
140-
/// CHECK(solution != nullptr);
141-
///
142-
/// - Inspect the solution cost and route (only one route here):
143-
///
144-
/// LOG(INFO) << "Cost " << solution->ObjectiveValue();
145-
/// const int route_number = 0;
146-
/// for (int64_t node = routing.Start(route_number);
147-
/// !routing.IsEnd(node);
148-
/// node = solution->Value(routing.NextVar(node))) {
149-
/// LOG(INFO) << manager.IndexToNode(node);
150-
/// }
151-
///
152-
///
153-
/// Keywords: Vehicle Routing, Traveling Salesman Problem, TSP, VRP, CVRPTW,
154-
/// PDP.
14+
/** @file routing.h
15+
@brief The vehicle routing library lets one model and solve generic vehicle
16+
routing problems ranging from the Traveling Salesman Problem to more complex
17+
problems such as the Capacitated Vehicle Routing Problem with Time Windows.
18+
@details The objective of a vehicle routing problem is to build routes covering
19+
a set of nodes minimizing the overall cost of the routes (usually proportional
20+
to the sum of the lengths of each segment of the routes) while respecting some
21+
problem-specific constraints (such as the length of a route). A route is
22+
equivalent to a path connecting nodes, starting/ending at specific
23+
starting/ending nodes.\n
24+
The term "vehicle routing" is historical and the category of problems solved
25+
is not limited to the routing of vehicles: any problem involving finding
26+
routes visiting a given number of nodes optimally falls under this category
27+
of problems, such as finding the optimal sequence in a playlist.\n
28+
The literature around vehicle routing problems is extremely dense but one
29+
can find some basic introductions in the following links:
30+
- http://en.wikipedia.org/wiki/Travelling_salesman_problem
31+
- http://en.wikipedia.org/wiki/Vehicle_routing_problem
32+
33+
The vehicle routing library is a vertical layer above the constraint
34+
programming library (ortools/constraint_programming:cp).\n
35+
One has access to all underlying constrained variables of the vehicle
36+
routing model which can therefore be enriched by adding any constraint
37+
available in the constraint programming library.\n
38+
There are two sets of variables available:
39+
- path variables:
40+
- "next(i)" variables representing the immediate successor of the node
41+
corresponding to i; use IndexToNode() to get the node corresponding to
42+
a "next" variable value; note that node indices are strongly typed
43+
integers (cf. ortools/base/int_type.h);
44+
- "vehicle(i)" variables representing the vehicle route to which the
45+
node corresponding to i belongs;
46+
- "active(i)" boolean variables, true if the node corresponding to i is
47+
visited and false if not; this can be false when nodes are either
48+
optional or part of a disjunction;
49+
- The following relationships hold for all i:
50+
active(i) == 0 <=> next(i) == i <=> vehicle(i) == -1,
51+
next(i) == j => vehicle(j) == vehicle(i).
52+
- dimension variables, used when one is accumulating quantities along
53+
routes, such as weight or volume carried, distance or time:
54+
- "cumul(i,d)" variables representing the quantity of dimension d when
55+
arriving at the node corresponding to i;
56+
- "transit(i,d)" variables representing the quantity of dimension d added
57+
after visiting the node corresponding to i.
58+
- The following relationship holds for all (i,d):
59+
next(i) == j => cumul(j,d) == cumul(i,d) + transit(i,d).
60+
61+
Solving the vehicle routing problems is mainly done using approximate
62+
methods (namely local search,
63+
cf. http://en.wikipedia.org/wiki/Local_search_(optimization) ), potentially
64+
combined with exact techniques based on dynamic programming and exhaustive
65+
tree search.
66+
TODO(user): Add a section on costs (vehicle arc costs, span costs,
67+
disjunctions costs).
68+
Advanced tips: Flags are available to tune the search used to solve routing
69+
problems. Here is a quick overview of the ones one might want to modify:
70+
- Limiting the search for solutions:
71+
- routing_solution_limit (default: kint64max): stop the search after
72+
finding 'routing_solution_limit' improving solutions;
73+
- routing_time_limit (default: kint64max): stop the search after
74+
'routing_time_limit' milliseconds;
75+
- Customizing search:
76+
- routing_first_solution (default: select the first node with an unbound
77+
successor and connect it to the first available node): selects the
78+
heuristic to build a first solution which will then be improved by local
79+
search; possible values are GlobalCheapestArc (iteratively connect two
80+
nodes which produce the cheapest route segment), LocalCheapestArc
81+
(select the first node with an unbound successor and connect it to the
82+
node which produces the cheapest route segment), PathCheapestArc
83+
(starting from a route "start" node, connect it to the node which
84+
produces the cheapest route segment, then extend the route by iterating
85+
on the last node added to the route).
86+
- Local search neighborhoods:
87+
- routing_no_lns (default: false): forbids the use of Large Neighborhood
88+
Search (LNS); LNS can find good solutions but is usually very slow.
89+
Refer to the description of PATHLNS in the LocalSearchOperators enum
90+
in constraint_solver.h for more information.
91+
- routing_no_tsp (default: true): forbids the use of exact methods to
92+
solve "sub"-traveling salesman problems (TSPs) of the current model
93+
(such as sub-parts of a route, or one route in a multiple route
94+
problem). Uses dynamic programming to solve such TSPs with a maximum
95+
size (in number of nodes) up to cp_local_search_tsp_opt_size (flag
96+
with a default value of 13 nodes). It is not activated by default
97+
because it can slow down the search.
98+
- Meta-heuristics: used to guide the search out of local minima found by
99+
local search. Note that, in general, a search with metaheuristics
100+
activated never stops, therefore one must specify a search limit.
101+
Several types of metaheuristics are provided:
102+
- routing_guided_local_search (default: false): activates guided local
103+
search (cf. http://en.wikipedia.org/wiki/Guided_Local_Search);
104+
this is generally the most efficient metaheuristic for vehicle
105+
routing;
106+
- routing_simulated_annealing (default: false): activates simulated
107+
annealing (cf. http://en.wikipedia.org/wiki/Simulated_annealing);
108+
- routing_tabu_search (default: false): activates tabu search (cf.
109+
http://en.wikipedia.org/wiki/Tabu_search).
110+
111+
Code sample:\n
112+
Here is a simple example solving a traveling salesman problem given a cost
113+
function callback (returns the cost of a route segment):
114+
- Define a custom distance/cost function from an index to another; in this
115+
example just returns the sum of the indices:
116+
@code{.cpp}
117+
int64_t MyDistance(int64_t from, int64_t to) {
118+
return from + to;
119+
}
120+
@endcode
121+
- Create a routing model for a given problem size (int number of nodes) and
122+
number of routes (here, 1):
123+
@code{.cpp}
124+
RoutingIndexManager manager(...number of nodes..., 1);
125+
RoutingModel routing(manager);
126+
@endcode
127+
- Set the cost function by registering an std::function<int64_t(int64_t,
128+
int64_t)> in the model and passing its index as the vehicle cost.
129+
@code{.cpp}
130+
const int cost = routing.RegisterTransitCallback(MyDistance);
131+
routing.SetArcCostEvaluatorOfAllVehicles(cost);
132+
@endcode
133+
- Find a solution using Solve(), returns a solution if any (owned by
134+
routing):
135+
@code{.cpp}
136+
const Assignment* solution = routing.Solve();
137+
CHECK(solution != nullptr);
138+
@endcode
139+
- Inspect the solution cost and route (only one route here):
140+
@code{.cpp}
141+
LOG(INFO) << "Cost " << solution->ObjectiveValue();
142+
const int route_number = 0;
143+
for (int64_t node = routing.Start(route_number);
144+
!routing.IsEnd(node);
145+
node = solution->Value(routing.NextVar(node))) {
146+
LOG(INFO) << manager.IndexToNode(node);
147+
}
148+
@endcode
149+
Keywords: Vehicle Routing, Traveling Salesman Problem, TSP, VRP, CVRPTW, PDP.
150+
*/
155151

156152
#ifndef ORTOOLS_CONSTRAINT_SOLVER_ROUTING_H_
157153
#define ORTOOLS_CONSTRAINT_SOLVER_ROUTING_H_
@@ -887,7 +883,7 @@ class OR_DLL RoutingModel {
887883
enum PenaltyCostBehavior { PENALIZE_ONCE, PENALIZE_PER_INACTIVE };
888884

889885
/// @brief Adds a disjunction constraint on the indices.
890-
/// @details exactly 'max_cardinality' of the indices are active.
886+
/// @details Exactly 'max_cardinality' of the indices are active.
891887
///
892888
/// If a penalty is given, at most 'max_cardinality' of the indices can be
893889
/// active, and if less are active, 'penalty' is payed per inactive index if
@@ -1093,10 +1089,8 @@ class OR_DLL RoutingModel {
10931089
/// Set the node visit types and incompatibilities/requirements between the
10941090
/// types (see below).
10951091
///
1096-
/// NOTE: Before adding any incompatibilities and/or requirements on types:
1097-
/// 1) All corresponding node types must have been set.
1098-
/// 2) CloseVisitTypes() must be called so all containers are resized
1099-
/// accordingly.
1092+
/// NOTE: Before adding any incompatibilities and/or requirements on types,
1093+
/// all corresponding node types must have been set.
11001094
///
11011095
/// The following enum is used to describe how a node with a given type 'T'
11021096
/// impacts the number of types 'T' on the route when visited, and thus

ortools/constraint_solver/routing_index_manager.h

Lines changed: 31 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -25,12 +25,14 @@
2525
#include "ortools/constraint_solver/routing_types.h"
2626
namespace operations_research {
2727

28-
/// Manager for any NodeIndex <-> variable index conversion. The routing solver
29-
/// uses variable indices internally and through its API. These variable indices
30-
/// are tricky to manage directly because one Node can correspond to a multitude
31-
/// of variables, depending on the number of times they appear in the model, and
32-
/// if they're used as start and/or end points. This class aims to simplify
33-
/// variable index usage, allowing users to use NodeIndex instead.
28+
/// @brief Manager for any NodeIndex <-> variable index conversion.
29+
/// @details The routing solver uses variable indices internally and through
30+
/// its API.
31+
/// These variable indices are tricky to manage directly because one Node can
32+
/// correspond to a multitude of variables, depending on the number of times
33+
/// they appear in the model, and if they're used as start and/or end points.
34+
/// This class aims to simplify variable index usage, allowing users to use
35+
/// NodeIndex instead.
3436
///
3537
/// Usage:
3638
/// \code{.cpp}
@@ -52,14 +54,32 @@ class OR_DLL RoutingIndexManager {
5254
typedef RoutingNodeIndex NodeIndex;
5355
static const int64_t kUnassigned;
5456

55-
/// Creates a NodeIndex to variable index mapping for a problem containing
56-
/// 'num_nodes', 'num_vehicles' and the given starts and ends for each
57-
/// vehicle. If used, any start/end arrays have to have exactly 'num_vehicles'
58-
/// elements.
57+
/// @brief Creates a NodeIndex to variable index mapping for a problem
58+
/// containing 'num_nodes', 'num_vehicles' and the given starts and ends for
59+
/// each vehicle. If used, any start/end arrays have to have exactly
60+
/// 'num_vehicles' elements.
61+
/// @param num_nodes Number of nodes in the problem.
62+
/// @param num_vehicles Number of vehicles in the problem.
63+
/// @param depot @ref GetStartIndex "start" and @ref GetEndIndex "end"
64+
/// NodeIndex for all vehicles.
5965
RoutingIndexManager(int num_nodes, int num_vehicles, NodeIndex depot);
66+
/// @brief Creates a NodeIndex to variable index mapping.
67+
/// @param num_nodes Number of nodes in the problem.
68+
/// @param num_vehicles Number of vehicles in the problem.
69+
/// @param starts Array containing the start NodeIndex for each vehicle.
70+
/// @param ends Array containing the end NodeIndex for each vehicle.
71+
/// @note @b starts and @b ends arrays must have @b exactly @ref num_vehicles
72+
/// elements.
6073
RoutingIndexManager(int num_nodes, int num_vehicles,
6174
const std::vector<NodeIndex>& starts,
6275
const std::vector<NodeIndex>& ends);
76+
/// @brief Creates a NodeIndex to variable index mapping.
77+
/// @param num_nodes Number of nodes in the problem.
78+
/// @param num_vehicles Number of vehicles in the problem.
79+
/// @param starts_ends Array containing a pair [start,end] NodeIndex for each
80+
/// vehicle.
81+
/// @note @b starts_ends arrays must have @b exactly @ref num_vehicles
82+
/// elements.
6383
RoutingIndexManager(
6484
int num_nodes, int num_vehicles,
6585
const std::vector<std::pair<NodeIndex, NodeIndex> >& starts_ends);
@@ -99,7 +119,7 @@ class OR_DLL RoutingIndexManager {
99119
absl::Span<const int64_t> indices) const;
100120
// TODO(user) Add unit tests for NodesToIndices and IndicesToNodes.
101121
// TODO(user): Remove when removal of NodeIndex from RoutingModel is
102-
/// complete.
122+
// complete.
103123
int num_unique_depots() const { return num_unique_depots_; }
104124
std::vector<NodeIndex> GetIndexToNodeMap() const { return index_to_node_; }
105125

0 commit comments

Comments
 (0)