Google OR-Tools v9.12
a fast and portable software suite for combinatorial optimization
Loading...
Searching...
No Matches
carp_parser.h
Go to the documentation of this file.
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// A parser for CARPLIB instances. The base files are available online, as well
15// as a description of the (Spanish-based) format:
16// https://www.uv.es/belengue/carp.html ("CARPLIB")
17// https://www.uv.es/~belengue/carp/READ_ME
18//
19// The goal is to find routes starting and ending at a depot which visit a
20// set of arcs (whereas a VRP visits nodes). The objective is to minimize the
21// total cost, which is due to either servicing an edge (i.e. performing the
22// required action) or traversing an edge (to get to another point in space).
23// Not all arcs/edges in the graph must be serviced.
24//
25// By this formulation, the total cost of servicing is known in advance.
26// All vehicles start at the same node, the depot, having index 1.
27// Servicing an edge requires resources, vehicles have a limited capacity. All
28// vehicles have the same capacity.
29//
30// The format of the data is the following:
31//
32// NOMBRE : <INSTANCE-NAME>
33// COMENTARIO : <ARBITRARY-COMMENT>
34// VERTICES : <NUMBER-OF-NODES, int>
35// ARISTAS_REQ : <NUMBER-OF-EDGES-WITH-NONZERO-SERVICING, int>
36// ARISTAS_NOREQ : <NUMBER-OF-EDGES-WITH-ZERO-SERVICING, int>
37// VEHICULOS : <NUMBER-OF-VEHICLES, int>
38// CAPACIDAD : <CAPACITY-OF-EACH-VEHICLE, int>
39// TIPO_COSTES_ARISTAS : EXPLICITOS
40// COSTE_TOTAL_REQ : <TOTAL-SERVICING-COST>
41// LISTA_ARISTAS_REQ :
42// ( <HEAD-NODE-OF-EDGE, int>, <TAIL-NODE-OF-EDGE, int> )
43// coste <TRAVERSING-COST, int> demanda <SERVICING, int>
44// <repeated, one edge per line>
45// LISTA_ARISTAS_NOREQ :
46// ( <HEAD-NODE-OF-EDGE, int>, <TAIL-NODE-OF-EDGE, int> )
47// coste <TRAVERSING-COST, int>
48// <repeated, one edge per line>
49// DEPOSITO : 1
50//
51// While the file format is defined with 1-based indexing, the output of the
52// parser is always 0-based. Users of this parser should never see any 1-based
53// index; only 0-based index should be used to query values.
54
55#ifndef OR_TOOLS_ROUTING_PARSERS_CARP_PARSER_H_
56#define OR_TOOLS_ROUTING_PARSERS_CARP_PARSER_H_
57
58#include <algorithm>
59#include <string>
60#include <string_view>
61#include <vector>
62
63#include "absl/strings/string_view.h"
64#include "absl/types/span.h"
68
71 public:
72 CarpParser();
73
74#ifndef SWIG
75 CarpParser(const CarpParser&) = delete;
76 const CarpParser& operator=(const CarpParser&) = delete;
77#endif
78
79 // Loads instance from a file into this parser object.
80 bool LoadFile(absl::string_view file_name);
81
82 // Returns the name of the instance being solved.
83 const std::string& name() const { return name_; }
84 // Returns the comment of the instance being solved, typically an upper bound.
85 const std::string& comment() const { return comment_; }
86 // Returns the index of the depot.
87 int64_t depot() const { return depot_; }
88 // Returns the number of nodes in the current routing problem.
89 int64_t NumberOfNodes() const { return number_of_nodes_; }
90 // Returns the number of edges in the current routing problem, with or
91 // without servicing required.
95 // Returns the number of edges in the current routing problem that require
96 // servicing.
98 return number_of_edges_with_servicing_;
99 }
100 // Returns the number of edges in the current routing problem that do not
101 // require servicing.
103 return number_of_edges_without_servicing_;
104 }
105 // Returns the total servicing cost for all arcs.
106 int64_t TotalServicingCost() const { return total_servicing_cost_; }
107 // Returns the servicing of the edges in the current routing problem.
109 return servicing_demands_;
110 }
111 // Returns the traversing costs of the edges in the current routing problem.
113 return traversing_costs_;
114 }
115 // Returns the maximum number of vehicles to use.
116 int64_t NumberOfVehicles() const { return n_vehicles_; }
117 // Returns the capacity of the vehicles.
118 int64_t capacity() const { return capacity_; }
119
120 // Returns the traversing cost for an edge. All edges are supposed to have
121 // a traversing cost.
122 int64_t GetTraversingCost(Edge edge) const {
123 CHECK(traversing_costs_.contains(edge))
124 << "Unknown edge: " << edge.tail() << " - " << edge.head();
125 return traversing_costs_.at(edge);
126 }
127 int64_t GetTraversingCost(int64_t tail, int64_t head) const {
128 return GetTraversingCost({tail, head});
129 }
130
131 // Checks whether this edge requires servicing.
132 int64_t HasServicingNeed(Edge edge) const {
133 return servicing_demands_.contains(edge);
134 }
135 int64_t HasServicingNeed(int64_t tail, int64_t head) const {
136 return HasServicingNeed({tail, head});
137 }
138
139 // Returns the servicing for an edge. Only a subset of edges have a servicing
140 // need.
141 int64_t GetServicing(Edge edge) const {
142 CHECK(HasServicingNeed(edge))
143 << "Unknown edge: " << edge.tail() << " - " << edge.head();
144 return servicing_demands_.at(edge);
145 }
146 int64_t GetServicing(int64_t tail, int64_t head) const {
147 return GetServicing({tail, head});
148 }
149
150 private:
151 // Parsing.
152 enum Section {
153 METADATA,
154 ARCS_WITH_SERVICING,
155 ARCS_WITHOUT_SERVICING,
156 UNDEFINED_SECTION
157 };
158
159 void Initialize();
160 bool ParseFile(absl::string_view file_name);
161 bool ParseMetadataLine(absl::Span<const std::string> words);
162 bool ParseEdge(std::string_view line, bool with_servicing);
163
164 // Parsing data.
165 Section section_;
166
167 // Instance data:
168 // - metadata
169 std::string name_;
170 std::string comment_;
171 int64_t number_of_nodes_;
172 int64_t number_of_edges_with_servicing_;
173 int64_t number_of_edges_without_servicing_;
174 int64_t total_servicing_cost_;
175 int64_t depot_;
176 // - graph costs and servicing demands. Keep track of the order of the
177 // demands: the output format requires to use the servicing-demands IDs,
178 // which are indices when iterating over this map.
179 gtl::linked_hash_map<Edge, int64_t> traversing_costs_;
180 gtl::linked_hash_map<Edge, int64_t> servicing_demands_;
181 // - vehicles
182 int64_t n_vehicles_;
183 int64_t capacity_;
184};
185} // namespace operations_research::routing
186
187#endif // OR_TOOLS_ROUTING_PARSERS_CARP_PARSER_H_
int64_t NumberOfVehicles() const
Returns the maximum number of vehicles to use.
const gtl::linked_hash_map< Edge, int64_t > & traversing_costs() const
Returns the traversing costs of the edges in the current routing problem.
int64_t GetServicing(Edge edge) const
int64_t depot() const
Returns the index of the depot.
Definition carp_parser.h:87
CarpParser(const CarpParser &)=delete
const std::string & name() const
Returns the name of the instance being solved.
Definition carp_parser.h:83
const std::string & comment() const
Returns the comment of the instance being solved, typically an upper bound.
Definition carp_parser.h:85
const gtl::linked_hash_map< Edge, int64_t > & servicing_demands() const
Returns the servicing of the edges in the current routing problem.
int64_t TotalServicingCost() const
Returns the total servicing cost for all arcs.
bool LoadFile(absl::string_view file_name)
Loads instance from a file into this parser object.
int64_t HasServicingNeed(Edge edge) const
Checks whether this edge requires servicing.
int64_t HasServicingNeed(int64_t tail, int64_t head) const
const CarpParser & operator=(const CarpParser &)=delete
int64_t GetServicing(int64_t tail, int64_t head) const
int64_t GetTraversingCost(Edge edge) const
int64_t GetTraversingCost(int64_t tail, int64_t head) const
int64_t capacity() const
Returns the capacity of the vehicles.
int64_t NumberOfNodes() const
Returns the number of nodes in the current routing problem.
Definition carp_parser.h:89
Common utilities for parsing routing instances.