Google OR-Tools v9.12
a fast and portable software suite for combinatorial optimization
Loading...
Searching...
No Matches
tsplib_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 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_PARSERS_TSPLIB_PARSER_H_
25#define OR_TOOLS_ROUTING_PARSERS_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"
34#include "absl/strings/string_view.h"
35#include "absl/types/span.h"
36#include "ortools/base/types.h"
38
40
41class TspLibParser final {
42 public:
43 // Routing model types (cf. the link above for a description).
45
47 // Loads and parses a routing problem from a given file.
48 bool LoadFile(absl::string_view file_name);
49 // Returns the number of nodes in the routing problem stored in a given file.
50 int SizeFromFile(absl::string_view file_name) const;
51 // Returns a function returning edge weights between nodes.
52 EdgeWeights GetEdgeWeights() const { return distance_function_; }
53 // Returns the index of the depot.
54 int depot() const { return depot_; }
55 // Returns the number of nodes in the current routing problem.
56 int size() const { return size_; }
57 // Returns the type of the current routing problem.
58 Types type() const { return type_; }
59 // Returns the coordinates of the nodes in the current routing problem (if
60 // they exist).
61 const std::vector<Coordinates3<double>>& coordinates() const {
62 return coords_;
63 }
64 // Returns the capacity of the vehicles in the current routing problem.
65 int64_t capacity() const { return capacity_; }
66 // Returns the maximal distance vehicles can travel.
67 int64_t max_distance() const { return max_distance_; }
68 // Returns the demands (or quantities picked up) at each node.
69 const std::vector<int64_t>& demands() const { return demands_; }
70 // Returns the pairs of nodes corresponding to forced edges (second node is
71 // directly after the first).
72 std::set<std::pair<int, int>> fixed_edges() const { return fixed_edges_; }
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 absl::Span<const 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(absl::Span<const std::string> words);
146 void ParseExplicitUpperRow(absl::Span<const std::string> words);
147 void ParseExplicitLowerRow(absl::Span<const std::string> words);
148 void ParseExplicitUpperDiagRow(absl::Span<const std::string> words);
149 void ParseExplicitLowerDiagRow(absl::Span<const std::string> words);
150 void ParseNodeCoord(absl::Span<const std::string> words);
151 void SetUpEdgeWeightSection();
152 void FinalizeEdgeWeights();
153 void ParseSections(absl::Span<const 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
197class TspLibTourParser final {
198 public:
200 // Loads and parses a given tour file.
201 bool LoadFile(absl::string_view 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
236class CVRPToursParser final {
237 public:
239 // Loads and parses a given tours file.
240 bool LoadFile(absl::string_view 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::routing
252
253#endif // OR_TOOLS_ROUTING_PARSERS_TSPLIB_PARSER_H_
bool LoadFile(absl::string_view file_name)
Loads and parses a given tours file.
const std::vector< std::vector< int > > & tours() const
Returns a vector corresponding to the sequence of nodes of tours.
bool LoadFile(absl::string_view file_name)
Loads and parses a routing problem from a given file.
int depot() const
Returns the index of the depot.
int64_t capacity() const
Returns the capacity of the vehicles in the current routing problem.
Types type() const
Returns the type of the current routing problem.
const std::vector< Coordinates3< double > > & coordinates() const
std::set< std::pair< int, int > > fixed_edges() const
EdgeWeights GetEdgeWeights() const
Returns a function returning edge weights between nodes.
std::string BuildTourFromRoutes(absl::Span< const std::vector< int > > routes) const
const std::vector< int64_t > & demands() const
Returns the demands (or quantities picked up) at each node.
Types
Routing model types (cf. the link above for a description).
int SizeFromFile(absl::string_view file_name) const
Returns the number of nodes in the routing problem stored in a given file.
const std::string & name() const
Returns the name of the current routing model.
int size() const
Returns the number of nodes in the current routing problem.
const std::string & comments() const
Returns the comments attached to the data.
const std::vector< std::vector< int > > & edges() const
int64_t max_distance() const
Returns the maximal distance vehicles can travel.
const std::string & comments() const
Returns the comments attached to the data.
int size() const
Returns the size of the tour.
bool LoadFile(absl::string_view file_name)
Loads and parses a given tour file.
const std::vector< int > & tour() const
Returns a vector corresponding to the sequence of nodes of the tour.
Common utilities for parsing routing instances.
std::function< int64_t(int, int)> EdgeWeights
Mapping between an edge (given by its tail and its head) and its weight.
trees with all degrees equal to