OR-Tools  9.6
tsplib_parser.h
Go to the documentation of this file.
1 // Copyright 2010-2022 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 TSPLIB parser. The TSPLIB is a library containing Traveling
15 // Salesman Problems and other vehicle routing problems.
16 // Limitations:
17 // - only TSP and CVRP files are currently supported.
18 // - XRAY1, XRAY2 and SPECIAL edge weight types are not supported.
19 //
20 // Takes as input a data file, potentially gzipped. The data must
21 // follow the TSPLIB95 format (described at
22 // http://www.iwr.uni-heidelberg.de/groups/comopt/software/TSPLIB95/DOC.PS).
23 
24 #ifndef OR_TOOLS_ROUTING_TSPLIB_PARSER_H_
25 #define OR_TOOLS_ROUTING_TSPLIB_PARSER_H_
26 
27 #include <functional>
28 #include <set>
29 #include <string>
30 #include <utility>
31 #include <vector>
32 
33 #include "absl/container/flat_hash_map.h"
36 
37 namespace operations_research {
38 
39 class TspLibParser final {
40  public:
41  // Routing model types (cf. the link above for a description).
43 
44  TspLibParser();
45  // Loads and parses a routing problem from a given file.
46  bool LoadFile(const std::string& file_name);
47  // Returns the number of nodes in the routing problem stored in a given file.
48  int SizeFromFile(const std::string& file_name) const;
49  // Returns a function returning edge weights between nodes.
50  EdgeWeights GetEdgeWeights() const { return distance_function_; }
51  // Returns the index of the depot.
52  int depot() const { return depot_; }
53  // Returns the number of nodes in the current routing problem.
54  int size() const { return size_; }
55  // Returns the type of the current routing problem.
56  Types type() const { return type_; }
57  // Returns the coordinates of the nodes in the current routing problem (if
58  // they exist).
59  const std::vector<Coordinates3<double>>& coordinates() const {
60  return coords_;
61  }
62  // Returns the capacity of the vehicles in the current routing problem.
63  int64_t capacity() const { return capacity_; }
64  // Returns the maximal distance vehicles can travel.
65  int64_t max_distance() const { return max_distance_; }
66  // Returns the demands (or quantities picked up) at each node.
67  const std::vector<int64_t>& demands() const { return demands_; }
68  // Returns the pairs of nodes corresponding to forced edges (second node is
69  // directly after the first).
70  const std::set<std::pair<int, int>> fixed_edges() const {
71  return fixed_edges_;
72  }
73  // Returns edges of the graph on which Hamiltonian cycles need to be built.
74  // Edges are represented as adjacency lists for each node.
75  const std::vector<std::vector<int>>& edges() const { return edges_; }
76  // Returns the name of the current routing model.
77  const std::string& name() const { return name_; }
78  // Returns the comments attached to the data.
79  const std::string& comments() const { return comments_; }
80  // Build a tour output in TSPLIB95 format from a vector of routes, a route
81  // being a sequence of node indices.
82  std::string BuildTourFromRoutes(
83  const std::vector<std::vector<int>>& routes) const;
84 
85  private:
86  enum Sections {
87  NAME,
88  TYPE,
89  COMMENT,
90  DIMENSION,
91  DISTANCE,
92  CAPACITY,
93  EDGE_DATA_FORMAT,
94  EDGE_DATA_SECTION,
95  EDGE_WEIGHT_TYPE,
96  EDGE_WEIGHT_FORMAT,
97  EDGE_WEIGHT_SECTION,
98  FIXED_EDGES_SECTION,
99  NODE_COORD_TYPE,
100  DISPLAY_DATA_TYPE,
101  DISPLAY_DATA_SECTION,
102  NODE_COORD_SECTION,
103  DEPOT_SECTION,
104  DEMAND_SECTION,
105  END_OF_FILE,
106  UNDEFINED_SECTION
107  };
108  enum EdgeDataFormat { EDGE_LIST, ADJ_LIST };
109  enum EdgeWeightTypes {
110  EXPLICIT,
111  EUC_2D,
112  EUC_3D,
113  MAX_2D,
114  MAX_3D,
115  MAN_2D,
116  MAN_3D,
117  CEIL_2D,
118  GEO,
119  GEOM,
120  ATT,
121  XRAY1,
122  XRAY2,
123  SPECIAL,
124  UNDEFINED_EDGE_WEIGHT_TYPE
125  };
126  enum EdgeWeightFormats {
127  FUNCTION,
128  FULL_MATRIX,
129  UPPER_ROW,
130  LOWER_ROW,
131  UPPER_DIAG_ROW,
132  LOWER_DIAG_ROW,
133  UPPER_COL,
134  LOWER_COL,
135  UPPER_DIAG_COL,
136  LOWER_DIAG_COL,
137  UNDEFINED_EDGE_WEIGHT_FORMAT
138  };
139 
140 #ifndef SWIG
141  TspLibParser(const TspLibParser&) = delete;
142  void operator=(const TspLibParser&) = delete;
143 #endif
144 
145  void ParseExplicitFullMatrix(const std::vector<std::string>& words);
146  void ParseExplicitUpperRow(const std::vector<std::string>& words);
147  void ParseExplicitLowerRow(const std::vector<std::string>& words);
148  void ParseExplicitUpperDiagRow(const std::vector<std::string>& words);
149  void ParseExplicitLowerDiagRow(const std::vector<std::string>& words);
150  void ParseNodeCoord(const std::vector<std::string>& words);
151  void SetUpEdgeWeightSection();
152  void FinalizeEdgeWeights();
153  void ParseSections(const std::vector<std::string>& words);
154  void ProcessNewLine(const std::string& line);
155  void SetExplicitCost(int from, int to, int64_t cost) {
156  if (explicit_costs_.size() != size_ * size_) {
157  explicit_costs_.resize(size_ * size_, 0);
158  }
159  explicit_costs_[from * size_ + to] = cost;
160  }
161 
162  // Model data
163  int64_t size_;
164  int64_t capacity_;
165  int64_t max_distance_;
166  std::vector<int64_t> demands_;
167  EdgeWeights distance_function_;
168  std::vector<int64_t> explicit_costs_;
169  std::set<std::pair<int, int>> fixed_edges_;
170  int depot_;
171  std::vector<std::vector<int>> edges_;
172 
173  // Parsing data
174  static const absl::flat_hash_map<std::string, Sections>* const kSections;
175  Sections section_;
176  static const absl::flat_hash_map<std::string, Types>* const kTypes;
177  Types type_;
178  static const absl::flat_hash_map<std::string, EdgeDataFormat>* const
179  kEdgeDataFormats;
180  EdgeDataFormat edge_data_format_;
181  static const absl::flat_hash_map<std::string, EdgeWeightTypes>* const
182  kEdgeWeightTypes;
183  EdgeWeightTypes edge_weight_type_;
184  static const absl::flat_hash_map<std::string, EdgeWeightFormats>* const
185  kEdgeWeightFormats;
186  EdgeWeightFormats edge_weight_format_;
187  int edge_row_;
188  int edge_column_;
189  std::vector<Coordinates3<double>> coords_;
190  std::string name_;
191  std::string comments_;
192  int64_t to_read_;
193 };
194 
195 // Class parsing tour (solution) data in TSLIB95 format.
196 
197 class TspLibTourParser final {
198  public:
200  // Loads and parses a given tour file.
201  bool LoadFile(const std::string& file_name);
202  // Returns a vector corresponding to the sequence of nodes of the tour.
203  const std::vector<int>& tour() const { return tour_; }
204  // Returns the size of the tour.
205  int size() const { return size_; }
206  // Returns the comments attached to the data.
207  const std::string& comments() const { return comments_; }
208 
209  private:
210  enum Sections {
211  NAME,
212  TYPE,
213  COMMENT,
214  DIMENSION,
215  TOUR_SECTION,
216  END_OF_FILE,
217  UNDEFINED_SECTION
218  };
219 
220 #ifndef SWIG
221  TspLibTourParser(const TspLibTourParser&) = delete;
222  void operator=(const TspLibTourParser&) = delete;
223 #endif
224 
225  void ProcessNewLine(const std::string& line);
226 
227  static const absl::flat_hash_map<std::string, Sections>* const kSections;
228  Sections section_;
229  std::string comments_;
230  int64_t size_;
231  std::vector<int> tour_;
232 };
233 
234 // Class parsing tours (solution) data in CVRPlib format.
235 
236 class CVRPToursParser final {
237  public:
238  CVRPToursParser();
239  // Loads and parses a given tours file.
240  bool LoadFile(const std::string& file_name);
241  // Returns a vector corresponding to the sequence of nodes of tours.
242  const std::vector<std::vector<int>>& tours() const { return tours_; }
243  int64_t cost() const { return cost_; }
244 
245  private:
246  void ProcessNewLine(const std::string& line);
247 
248  std::vector<std::vector<int>> tours_;
249  int64_t cost_;
250 };
251 } // namespace operations_research
252 
253 #endif // OR_TOOLS_ROUTING_TSPLIB_PARSER_H_
bool LoadFile(const std::string &file_name)
const std::vector< std::vector< int > > & tours() const
const std::vector< Coordinates3< double > > & coordinates() const
Definition: tsplib_parser.h:59
const std::vector< int64_t > & demands() const
Definition: tsplib_parser.h:67
EdgeWeights GetEdgeWeights() const
Definition: tsplib_parser.h:50
int SizeFromFile(const std::string &file_name) const
bool LoadFile(const std::string &file_name)
const std::vector< std::vector< int > > & edges() const
Definition: tsplib_parser.h:75
const std::set< std::pair< int, int > > fixed_edges() const
Definition: tsplib_parser.h:70
const std::string & comments() const
Definition: tsplib_parser.h:79
std::string BuildTourFromRoutes(const std::vector< std::vector< int >> &routes) const
const std::string & name() const
Definition: tsplib_parser.h:77
bool LoadFile(const std::string &file_name)
const std::string & comments() const
const std::vector< int > & tour() const
Collection of objects used to extend the Constraint Solver library.
std::function< int64_t(int, int)> EdgeWeights
Definition: simple_graph.h:89
int line
Definition: parse_proto.cc:31
int64_t cost