21 #include "absl/container/btree_set.h"
22 #include "absl/flags/flag.h"
23 #include "absl/strings/str_format.h"
24 #include "absl/strings/string_view.h"
25 #include "gtest/gtest.h"
35 #define ROOT_DIR "../../../../../../../"
40 ABSL_FLAG(std::string, test_srcdir,
"",
"REQUIRED: src dir");
45 TEST(TspLibParserTest, GeneratedDataSets) {
46 static const char kName[] =
"GoogleTest";
47 static const char*
const kTypes[] = {
"TSP",
"CVRP"};
48 static const char kComment[] =
"This is a test";
49 static const int kDimension = 4;
50 static const int kCoordSize = 2;
52 static const char*
const kEdgeWeightTypes[] = {
53 "EXPLICIT",
"EUC_2D",
"EUC_3D",
"MAX_2D",
"MAX_3D",
54 "MAN_2D",
"MAN_3D",
"CEIL_2D",
"GEO",
"ATT"};
55 static const char*
const kEdgeWeightFormats[] = {
56 "FULL_MATRIX",
"UPPER_ROW",
"LOWER_ROW",
57 "UPPER_DIAG_ROW",
"LOWER_DIAG_ROW",
"UPPER_COL",
58 "LOWER_COL",
"UPPER_DIAG_COL",
"LOWER_DIAG_COL"};
59 static const char*
const kNodeCoordTypes[] = {
"TWOD_COORDS",
"THREED_COORDS",
61 static const char*
const kDisplayDataTypes[] = {
"COORD_DISPLAY",
62 "TWOD_DISPLAY",
"NO_DISPLAY"};
63 for (
int type = 0; type < ABSL_ARRAYSIZE(kTypes); ++type) {
64 for (
int edge_type = 0; edge_type < ABSL_ARRAYSIZE(kEdgeWeightTypes);
66 for (
int edge_format = 0;
67 edge_format < ABSL_ARRAYSIZE(kEdgeWeightFormats); ++edge_format) {
68 for (
int node_type = 0; node_type < ABSL_ARRAYSIZE(kNodeCoordTypes);
70 if (node_type == 2 && edge_type != 0)
break;
71 if (node_type == 1 && edge_type != 2 && edge_type != 4 &&
74 if (node_type == 0 && edge_type != 1 && edge_type != 3 &&
75 edge_type != 5 && edge_type < 7)
77 for (
int display_type = 0;
78 display_type < ABSL_ARRAYSIZE(kDisplayDataTypes);
80 if (display_type == 0 && node_type == 2)
break;
81 std::string data = absl::StrFormat(
"NAME: %s\n", kName);
82 absl::StrAppendFormat(&data,
"TYPE: %s\n", kTypes[type]);
83 absl::StrAppendFormat(&data,
"COMMENT: %s\n", kComment);
84 absl::StrAppendFormat(&data,
"DIMENSION: %d\n", kDimension);
86 absl::StrAppendFormat(&data,
"CAPACITY: %d\n",
kCapacity);
88 absl::StrAppendFormat(&data,
"EDGE_WEIGHT_TYPE: %s\n",
89 kEdgeWeightTypes[edge_type]);
91 absl::StrAppendFormat(&data,
"EDGE_WEIGHT_FORMAT: %s\n",
92 kEdgeWeightFormats[edge_format]);
94 absl::StrAppendFormat(&data,
"NODE_COORD_TYPE: %s\n",
95 kNodeCoordTypes[node_type]);
96 absl::StrAppendFormat(&data,
"DISPLAY_DATA_TYPE: %s\n",
97 kDisplayDataTypes[display_type]);
99 data +=
"NODE_COORD_SECTION\n";
100 for (
int i = 0; i < kDimension; ++i) {
101 absl::StrAppendFormat(&data,
"%d %d %d", i + 1, i % kCoordSize,
103 if (node_type == 1) {
110 data +=
"DEPOT_SECTION\n1\n-1\n";
111 data +=
"DEMAND_SECTION\n";
112 for (
int i = 0; i < kDimension; ++i) {
113 absl::StrAppendFormat(&data,
"%d %d\n", i + 1, 1);
116 if (display_type == 1) {
117 data +=
"DISPLAY_DATA_SECTION\n";
118 for (
int i = 0; i < kDimension; ++i) {
119 absl::StrAppendFormat(&data,
"%d %d %d\n", i + 1,
120 i % kCoordSize, i / kCoordSize);
123 if (edge_type == 0) {
124 data +=
"EDGE_WEIGHT_SECTION\n";
126 switch (edge_format) {
128 for (
int i = 0; i < kDimension; ++i) {
129 const int x = i % kCoordSize;
130 const int y = i / kCoordSize;
131 for (
int j = 0; j < kDimension; ++j) {
133 abs(x - (j % kCoordSize)) + abs(y - (j / kCoordSize));
134 absl::StrAppendFormat(&data,
"%d ",
distance);
141 for (
int i = 0; i < kDimension; ++i) {
142 const int x = i % kCoordSize;
143 const int y = i / kCoordSize;
144 for (
int j = i + 1; j < kDimension; ++j) {
146 abs(x - (j % kCoordSize)) + abs(y - (j / kCoordSize));
147 absl::StrAppendFormat(&data,
"%d ",
distance);
154 for (
int i = 0; i < kDimension; ++i) {
155 const int x = i % kCoordSize;
156 const int y = i / kCoordSize;
157 for (
int j = 0; j < i; ++j) {
159 abs(x - (j % kCoordSize)) + abs(y - (j / kCoordSize));
160 absl::StrAppendFormat(&data,
"%d ",
distance);
167 for (
int i = 0; i < kDimension; ++i) {
168 const int x = i % kCoordSize;
169 const int y = i / kCoordSize;
170 for (
int j = i; j < kDimension; ++j) {
172 abs(x - (j % kCoordSize)) + abs(y - (j / kCoordSize));
173 absl::StrAppendFormat(&data,
"%d ",
distance);
180 for (
int i = 0; i < kDimension; ++i) {
181 const int x = i % kCoordSize;
182 const int y = i / kCoordSize;
183 for (
int j = 0; j <= i; ++j) {
185 abs(x - (j % kCoordSize)) + abs(y - (j / kCoordSize));
186 absl::StrAppendFormat(&data,
"%d ",
distance);
194 const std::string kMMFileName{std::tmpnam(
nullptr)};
197 EXPECT_TRUE(parser.LoadFile(kMMFileName));
198 EXPECT_EQ(kDimension, parser.SizeFromFile(kMMFileName));
206 TEST(TspLibParserTest, ParseHCPEdgeList) {
207 static const char* kData =
212 "EDGE_DATA_FORMAT : EDGE_LIST\n"
213 "EDGE_DATA_SECTION\n"
217 const std::string kMMFileName{std::tmpnam(
nullptr)};
220 EXPECT_TRUE(parser.LoadFile(kMMFileName));
221 EXPECT_EQ(3, parser.SizeFromFile(kMMFileName));
222 EXPECT_EQ(2, parser.edges()[0].size());
223 EXPECT_EQ(1, parser.edges()[0][0]);
224 EXPECT_EQ(2, parser.edges()[0][1]);
225 EXPECT_EQ(0, parser.edges()[1].size());
226 EXPECT_EQ(0, parser.edges()[2].size());
229 TEST(TspLibParserTest, ParseHCPAdjList) {
230 static const char* kData =
235 "EDGE_DATA_FORMAT : ADJ_LIST\n"
236 "EDGE_DATA_SECTION\n"
239 const std::string kMMFileName{std::tmpnam(
nullptr)};
242 EXPECT_TRUE(parser.LoadFile(kMMFileName));
243 EXPECT_EQ(3, parser.SizeFromFile(kMMFileName));
244 EXPECT_EQ(1, parser.edges()[0].size());
245 EXPECT_EQ(2, parser.edges()[0][0]);
246 EXPECT_EQ(1, parser.edges()[1].size());
247 EXPECT_EQ(2, parser.edges()[1][0]);
248 EXPECT_EQ(0, parser.edges()[2].size());
251 TEST(TspLibParserTest, ParseKytojoki33Depot) {
253 std::string file_name =
file::JoinPath(absl::GetFlag(FLAGS_test_srcdir),
254 ROOT_DIR "ortools/routing/testdata/",
255 "tsplib_Kytojoki_33.vrp");
257 EXPECT_TRUE(parser.LoadFile(file_name));
260 EXPECT_EQ(2400, parser.depot());
261 EXPECT_EQ(0, parser.edges().size());
262 EXPECT_EQ(0.0, parser.coordinates()[parser.depot()].x);
263 EXPECT_EQ(0.0, parser.coordinates()[parser.depot()].y);
266 TEST(TspLibTourParserTest, LoadAllDataSets) {
267 static const char kArchive[] =
268 ROOT_DIR "operations_research_data/TSPLIB95/ALL_tsp.tar.gz";
269 static const char* kExpectedComments[] = {
271 ": Optimum solution for att48",
272 ": Optimum solution of bayg29",
273 ": Optimum solution of bays29",
278 ": Optimum tour for eil101.tsp (Length 629)",
279 ": Optimal tour for eil51.tsp (426)",
280 ": Optimum tour for eil76.tsp (538)",
281 ": optimal tour for fri26 (937)",
282 ": Optimal tour for gr120 (6942)",
283 ": Optimal solution for gr202 (40160)",
284 ": Optimal solution for gr24 (1272)",
285 ": Optimal solution for gr48 (5046)",
286 ": Optimal solution of gr666 (294358)",
287 ": Optimal tour for gr96 (55209)",
288 ": Optimum tour for kroA100 (21282)",
289 ": Optimal tour for kroC100 (20749)",
290 ": Optimal tour for kroD100 (21294)",
291 ": Optimal tour for lin105 (14379)",
292 ": Optimal tour for pa561 (2763)",
293 ": Optimal solution for pcb442 (50778)",
294 ": optimal tour for pr1002 (259045)",
295 ": Optimal solution for pr2392 (378032)",
296 ": Optimal tour for pr76 (108159)",
297 ": Optimal solution for rd100 (7910)",
298 ": Optimal tour for st70 (675)",
299 ": Optimal solution for tsp225 (3919)",
300 ": Optimal solution for ulysses16 (6859)",
301 ": Optimal solution of ulysses22 (7013)"};
303 std::vector<std::string> matches;
305 kArchive,
"*\\.opt\\.tour\\.gz"),
308 for (
const std::string& match : matches) {
309 TspLibTourParser parser;
310 EXPECT_TRUE(parser.LoadFile(match));
311 EXPECT_EQ(kExpectedComments[file_index], parser.comments());
317 TEST(CVRPToursParserTest, LoadAllDataSets) {
318 static const char kArchive[] =
319 ROOT_DIR "operations_research_data/CVRP/Augerat/A-VRP-sol.zip";
320 static const int kExpectedCosts[] = { 784,
338 std::vector<std::string> matches;
340 kArchive,
"opt-A-\\.*"),
343 for (
const std::string& match : matches) {
344 CVRPToursParser parser;
345 EXPECT_TRUE(parser.LoadFile(match));
346 EXPECT_EQ(kExpectedCosts[file_index], parser.cost());
absl::Status Match(std::string_view pattern, std::vector< std::string > *result, const file::Options &options)
std::string JoinPath(absl::string_view path1, absl::string_view path2)
Collection of objects used to extend the Constraint Solver library.
TEST(LinearAssignmentTest, NullMatrix)
ABSL_FLAG(std::string, test_srcdir, "", "REQUIRED: src dir")