20 #include "gtest/gtest.h"
25 TEST(RoutingSolutionSerializerTest, RoutingSolutionEventComparison) {
46 TEST(RoutingSolutionSerializerTest, ParseEmptyString) {
50 TEST(RoutingSolutionSerializerTest, ParseUnrecognizedString) {
55 TEST(RoutingSolutionSerializerTest, ParseNoneString) {
59 TEST(RoutingSolutionSerializerTest, ParseTsplibString) {
66 TEST(RoutingSolutionSerializerTest, ParseCvrplibString) {
73 TEST(RoutingSolutionSerializerTest, ParseCarplibString) {
80 TEST(RoutingSolutionSerializerTest, ParseNearplibString) {
87 TEST(RoutingSolutionSerializerTest, FromSplitRoutesWithOneRoute) {
89 const std::vector<std::vector<int64_t>> routes{{0, 1, 3, 0}};
92 const RoutingSolution expected_output = RoutingSolution{
105 std::vector<int64_t>{-1},
106 std::vector<int64_t>{-1},
108 EXPECT_EQ(result, expected_output);
111 TEST(RoutingSolutionSerializerTest, FromSplitRoutesWithTwoRoutes) {
113 const std::vector<std::vector<int64_t>> routes{
119 const RoutingSolution expected_output = {RoutingSolution{
120 std::vector<RoutingSolution::Route>{
144 std::vector<int64_t>{-1, -1},
145 std::vector<int64_t>{-1, -1},
148 EXPECT_EQ(result, expected_output);
151 TEST(RoutingSolutionSerializerTest, SolutionToTsplib) {
152 const std::vector<int64_t> solution{0, 1, 2, 3, 0, -1, 0, 4, 5, 6, 0, -1};
153 const std::string expected_output =
"0\n1\n2\n3\n0\n-1\n0\n4\n5\n6\n0\n-1\n";
160 TEST(RoutingSolutionSerializerTest, SolutionToTsplibFile) {
161 const std::string file_name{std::tmpnam(
nullptr)};
164 const std::vector<std::vector<int64_t>> solution_vector{{0, 1, 2, 3, 0},
166 const std::string expected_output =
168 "COMMENT : Length = -1; Total time = -1.000000 s\n"
172 "0\n1\n2\n3\n0\n-1\n0\n4\n5\n6\n0\n-1\n"
175 RoutingSolution solution =
177 solution.SetName(
"Test name");
179 std::string written_solution;
181 EXPECT_EQ(written_solution, expected_output);
184 TEST(RoutingSolutionSerializerTest, SolutionToCvrplib) {
186 const std::vector<int64_t> solution{1, 2, 3, 1, -1, 1, 4, 5, 6, 1, -1};
187 const std::string expected_output =
"Route #1: 1 2\nRoute #2: 3 4 5\n";
195 TEST(RoutingSolutionSerializerTest, SolutionToCvrplibInvalidNoStart) {
196 const std::vector<RoutingSolution::Route> routes = {
204 const RoutingSolution solution{routes, {4}, {4}};
205 std::string solution_str;
212 TEST(RoutingSolutionSerializerTest, SolutionToCvrplibInvalidNoEnd) {
213 const std::vector<RoutingSolution::Route> routes = {
221 const RoutingSolution solution{routes, {4}, {4}};
222 std::string solution_str;
229 TEST(RoutingSolutionSerializerTest, SolutionToCvrplibDepot0Dimacs) {
232 const std::vector<int64_t> solution{0, 1, 4, 0, -1, 0, 3, 2, 5, 0, -1};
233 const std::string expected_output =
"Route #1: 1 4\nRoute #2: 3 2 5\n";
241 TEST(RoutingSolutionSerializerTest, SolutionToCvrplibDepot1Dimacs) {
244 const std::vector<int64_t> solution{1, 2, 5, 1, -1, 1, 4, 3, 6, 1, -1};
245 const std::string expected_output =
"Route #1: 1 4\nRoute #2: 3 2 5\n";
253 TEST(RoutingSolutionSerializerTest, SolutionToCvrplibFile) {
254 const std::string file_name{std::tmpnam(
nullptr)};
257 const std::vector<std::vector<int64_t>> solution_vector{{0, 1, 2, 3, 0},
259 const std::string expected_output =
264 RoutingSolution solution =
266 solution.SetTotalCost(4857);
268 std::string written_solution;
270 EXPECT_EQ(written_solution, expected_output);
273 RoutingSolution MakeTestArcRoutingInstance() {
274 using Event = RoutingSolution::Event;
275 using Type = Event::Type;
276 return {std::vector<RoutingSolution::Route>{
278 Event{Type::kStart, 0, Arc{0, 0}},
279 Event{Type::kServeArc, 12, Arc{4, 10},
"A1"},
280 Event{Type::kServeArc, 21, Arc{10, 8},
"A2"},
281 Event{Type::kServeArc, 8, Arc{8, 1},
"A3"},
282 Event{Type::kServeArc, 7, Arc{1, 3},
"A4"},
283 Event{Type::kServeArc, 2, Arc{3, 0},
"A5"},
284 Event{Type::kEnd, 0, Arc{0, 0}},
287 Event{Type::kStart, 0, Arc{0, 0}},
288 Event{Type::kServeArc, 5, Arc{0, 11},
"A6"},
289 Event{Type::kServeArc, 14, Arc{5, 6},
"A7"},
290 Event{Type::kServeArc, 19, Arc{7, 10},
"A8"},
291 Event{Type::kServeArc, 22, Arc{10, 9},
"A9"},
292 Event{Type::kServeArc, 4, Arc{9, 0},
"A10"},
293 Event{Type::kEnd, 0, Arc{0, 0}},
296 Event{Type::kStart, 0, Arc{0, 0}},
297 Event{Type::kServeArc, 13, Arc{11, 4},
"A11"},
298 Event{Type::kServeArc, 9, Arc{2, 3},
"A12"},
299 Event{Type::kServeArc, 6, Arc{1, 2},
"A13"},
300 Event{Type::kServeArc, 10, Arc{2, 4},
"A14"},
301 Event{Type::kServeArc, 11, Arc{4, 5},
"A15"},
302 Event{Type::kEnd, 0, Arc{0, 0}},
305 Event{Type::kStart, 0, Arc{0, 0}},
306 Event{Type::kServeArc, 15, Arc{11, 5},
"A16"},
307 Event{Type::kServeArc, 16, Arc{6, 7},
"A17"},
308 Event{Type::kServeArc, 18, Arc{7, 9},
"A18"},
309 Event{Type::kServeArc, 20, Arc{9, 8},
"A19"},
310 Event{Type::kServeArc, 1, Arc{1, 0},
"A20"},
311 Event{Type::kEnd, 0, Arc{0, 0}},
314 Event{Type::kStart, 0, Arc{0, 0}},
315 Event{Type::kServeArc, 17, Arc{11, 6},
"A21"},
316 Event{Type::kServeArc, 3, Arc{6, 0},
"A22"},
317 Event{Type::kEnd, 0, Arc{0, 0}},
320 std::vector<int64_t>{5, 5, 5, 5, 2},
321 std::vector<int64_t>{76, 60, 86, 53, 41},
327 RoutingSolution MakeTestEdgeNodeArcRoutingInstance() {
328 using Event = RoutingSolution::Event;
329 using Type = Event::Type;
330 return {std::vector<RoutingSolution::Route>{
332 Event{Type::kStart, 0, Arc{0, 0}},
333 Event{Type::kTransit, -1, Arc{0, 4}},
334 Event{Type::kServeEdge, 12, Arc{4, 10},
"E1"},
335 Event{Type::kServeArc, 21, Arc{10, 8},
"A2"},
336 Event{Type::kServeNode, 8, Arc{8, 8}},
337 Event{Type::kTransit, -1, Arc{8, 1}},
338 Event{Type::kServeEdge, 7, Arc{1, 3},
"E3"},
339 Event{Type::kServeArc, 2, Arc{3, 0},
"A4"},
340 Event{Type::kEnd, 0, Arc{0, 0}},
343 Event{Type::kStart, 0, Arc{0, 0}},
344 Event{Type::kServeEdge, 5, Arc{0, 11},
"E5"},
345 Event{Type::kTransit, -1, Arc{11, 5}},
346 Event{Type::kServeEdge, 14, Arc{5, 6},
"E6"},
347 Event{Type::kTransit, -1, Arc{6, 7}},
348 Event{Type::kServeEdge, 19, Arc{7, 10},
"E7"},
349 Event{Type::kServeEdge, 22, Arc{10, 9},
"E8"},
350 Event{Type::kServeEdge, 4, Arc{9, 0},
"E9"},
351 Event{Type::kEnd, 0, Arc{0, 0}},
354 Event{Type::kStart, 0, Arc{0, 0}},
355 Event{Type::kTransit, -1, Arc{0, 11}},
356 Event{Type::kServeArc, 13, Arc{11, 4},
"A10"},
357 Event{Type::kTransit, -1, Arc{4, 2}},
358 Event{Type::kServeEdge, 9, Arc{2, 3},
"E11"},
359 Event{Type::kTransit, -1, Arc{3, 1}},
360 Event{Type::kServeArc, 6, Arc{1, 2},
"A12"},
361 Event{Type::kServeNode, 10, Arc{2, 2}},
362 Event{Type::kTransit, -1, Arc{2, 4}},
363 Event{Type::kServeEdge, 11, Arc{4, 5},
"E13"},
364 Event{Type::kTransit, -1, Arc{5, 0}},
365 Event{Type::kEnd, 0, Arc{0, 0}},
368 Event{Type::kStart, 0, Arc{0, 0}},
369 Event{Type::kTransit, -1, Arc{0, 11}},
370 Event{Type::kServeNode, 15, Arc{11, 11}},
371 Event{Type::kServeEdge, 16, Arc{11, 7},
"E14"},
372 Event{Type::kServeEdge, 18, Arc{7, 9},
"E15"},
373 Event{Type::kServeEdge, 20, Arc{9, 8},
"E16"},
374 Event{Type::kTransit, -1, Arc{8, 1}},
375 Event{Type::kServeEdge, 1, Arc{1, 0},
"E17"},
376 Event{Type::kEnd, 0, Arc{0, 0}},
379 Event{Type::kStart, 0, Arc{0, 0}},
380 Event{Type::kTransit, -1, Arc{0, 11}},
381 Event{Type::kServeNode, 17, Arc{11, 11}},
382 Event{Type::kTransit, -1, Arc{11, 6}},
383 Event{Type::kServeNode, 3, Arc{6, 6}},
384 Event{Type::kTransit, -1, Arc{6, 0}},
385 Event{Type::kEnd, 0, Arc{0, 0}},
388 std::vector<int64_t>{5, 5, 5, 5, 2},
389 std::vector<int64_t>{76, 60, 86, 53, 41},
395 TEST(RoutingSolutionSerializerTest, CarpSolutionToCarplib) {
397 const std::string expected_solution_output =
398 "0 1 1 5 76 7 (D 0,1,1) (S 12,5,11) (S 21,11,9) (S 8,9,2) (S 7,2,4) "
399 "(S 2,4,1) (D 0,1,1)\n"
400 "0 1 2 5 60 7 (D 0,1,1) (S 5,1,12) (S 14,6,7) (S 19,8,11) (S 22,11,10) "
401 "(S 4,10,1) (D 0,1,1)\n"
402 "0 1 3 5 86 7 (D 0,1,1) (S 13,12,5) (S 9,3,4) (S 6,2,3) (S 10,3,5) "
403 "(S 11,5,6) (D 0,1,1)\n"
404 "0 1 4 5 53 7 (D 0,1,1) (S 15,12,6) (S 16,7,8) (S 18,8,10) (S 20,10,9) "
405 "(S 1,2,1) (D 0,1,1)\n"
406 "0 1 5 2 41 4 (D 0,1,1) (S 17,12,7) (S 3,7,1) (D 0,1,1)";
408 const RoutingSolution solution = MakeTestArcRoutingInstance();
410 expected_solution_output);
413 TEST(RoutingSolutionSerializerTest, CarpSolutionToCarplibFile) {
414 const std::string file_name{std::tmpnam(
nullptr)};
417 RoutingSolution solution = MakeTestArcRoutingInstance();
418 const std::string expected_output =
422 "0 1 1 5 76 7 (D 0,1,1) (S 12,5,11) (S 21,11,9) (S 8,9,2) (S 7,2,4) "
423 "(S 2,4,1) (D 0,1,1)\n"
424 "0 1 2 5 60 7 (D 0,1,1) (S 5,1,12) (S 14,6,7) (S 19,8,11) (S 22,11,10) "
425 "(S 4,10,1) (D 0,1,1)\n"
426 "0 1 3 5 86 7 (D 0,1,1) (S 13,12,5) (S 9,3,4) (S 6,2,3) (S 10,3,5) "
427 "(S 11,5,6) (D 0,1,1)\n"
428 "0 1 4 5 53 7 (D 0,1,1) (S 15,12,6) (S 16,7,8) (S 18,8,10) (S 20,10,9) "
429 "(S 1,2,1) (D 0,1,1)\n"
430 "0 1 5 2 41 4 (D 0,1,1) (S 17,12,7) (S 3,7,1) (D 0,1,1)";
431 solution.SetName(
"Test name");
434 std::string written_solution;
436 EXPECT_EQ(written_solution, expected_output);
439 TEST(RoutingSolutionSerializerTest, NearpSolutionToCarplib) {
440 const std::string expected_solution_output =
441 "0 1 1 5 76 7 (D 0,1,1) (S 12,5,11) (S 21,11,9) (S 8,9,9) (S 7,2,4) "
442 "(S 2,4,1) (D 0,1,1)\n"
443 "0 1 2 5 60 7 (D 0,1,1) (S 5,1,12) (S 14,6,7) (S 19,8,11) (S 22,11,10) "
444 "(S 4,10,1) (D 0,1,1)\n"
445 "0 1 3 5 86 7 (D 0,1,1) (S 13,12,5) (S 9,3,4) (S 6,2,3) (S 10,3,3) "
446 "(S 11,5,6) (D 0,1,1)\n"
447 "0 1 4 5 53 7 (D 0,1,1) (S 15,12,12) (S 16,12,8) (S 18,8,10) (S 20,10,9) "
448 "(S 1,2,1) (D 0,1,1)\n"
449 "0 1 5 2 41 4 (D 0,1,1) (S 17,12,12) (S 3,7,7) (D 0,1,1)";
451 const RoutingSolution solution = MakeTestEdgeNodeArcRoutingInstance();
453 expected_solution_output);
456 TEST(RoutingSolutionSerializerTest, NearpSolutionToCarplibFile) {
457 const std::string file_name{std::tmpnam(
nullptr)};
460 RoutingSolution solution = MakeTestEdgeNodeArcRoutingInstance();
461 const std::string expected_output =
465 "0 1 1 5 76 7 (D 0,1,1) (S 12,5,11) (S 21,11,9) (S 8,9,9) (S 7,2,4) "
466 "(S 2,4,1) (D 0,1,1)\n"
467 "0 1 2 5 60 7 (D 0,1,1) (S 5,1,12) (S 14,6,7) (S 19,8,11) (S 22,11,10) "
468 "(S 4,10,1) (D 0,1,1)\n"
469 "0 1 3 5 86 7 (D 0,1,1) (S 13,12,5) (S 9,3,4) (S 6,2,3) (S 10,3,3) "
470 "(S 11,5,6) (D 0,1,1)\n"
471 "0 1 4 5 53 7 (D 0,1,1) (S 15,12,12) (S 16,12,8) (S 18,8,10) (S 20,10,9) "
472 "(S 1,2,1) (D 0,1,1)\n"
473 "0 1 5 2 41 4 (D 0,1,1) (S 17,12,12) (S 3,7,7) (D 0,1,1)";
474 solution.SetName(
"Test name");
477 std::string written_solution;
479 EXPECT_EQ(written_solution, expected_output);
482 TEST(RoutingSolutionSerializerTest, CarpSolutionToNearplib) {
483 const std::string expected_solution_output =
484 "Route #1 : 1 5-A1-11-A2-9-A3-2-A4-4-A5-1\n"
485 "Route #2 : 1-A6-12 6-A7-7 8-A8-11-A9-10-A10-1\n"
486 "Route #3 : 1 12-A11-5 3-A12-4 2-A13-3-A14-5-A15-6 1\n"
487 "Route #4 : 1 12-A16-6 7-A17-8-A18-10-A19-9 2-A20-1\n"
488 "Route #5 : 1 12-A21-7-A22-1";
490 const RoutingSolution solution = MakeTestArcRoutingInstance();
492 expected_solution_output);
495 TEST(RoutingSolutionSerializerTest, CarpSolutionToNearplibFile) {
496 const std::string file_name{std::tmpnam(
nullptr)};
499 RoutingSolution solution = MakeTestArcRoutingInstance();
500 const std::string date =
501 absl::FormatTime(
"%B %d, %E4Y", absl::Now(), absl::LocalTimeZone());
502 const std::string expected_output =
503 "Instance name: Test name\n"
504 "Authors: DIMACS CARP\n"
508 "Reference: OR-Tools\n"
510 "Route #1 : 1 5-A1-11-A2-9-A3-2-A4-4-A5-1\n"
511 "Route #2 : 1-A6-12 6-A7-7 8-A8-11-A9-10-A10-1\n"
512 "Route #3 : 1 12-A11-5 3-A12-4 2-A13-3-A14-5-A15-6 1\n"
513 "Route #4 : 1 12-A16-6 7-A17-8-A18-10-A19-9 2-A20-1\n"
514 "Route #5 : 1 12-A21-7-A22-1\n"
516 solution.SetName(
"Test name");
517 solution.SetAuthors(
"DIMACS CARP");
520 std::string written_solution;
522 EXPECT_EQ(written_solution, expected_output);
525 TEST(RoutingSolutionSerializerTest, NearpSolutionToNearplib) {
526 const std::string expected_solution_output =
527 "Route #1 : 1 5-E1-11-A2-9 N9 2-E3-4-A4-1\n"
528 "Route #2 : 1-E5-12 6-E6-7 8-E7-11-E8-10-E9-1\n"
529 "Route #3 : 1 12-A10-5 3-E11-4 2-A12-3 N3 5-E13-6 1\n"
530 "Route #4 : 1 N12-E14-8-E15-10-E16-9 2-E17-1\n"
531 "Route #5 : 1 N12 N7 1";
538 const RoutingSolution solution = MakeTestEdgeNodeArcRoutingInstance();
540 expected_solution_output);
543 TEST(RoutingSolutionSerializerTest, NearpSolutionToNearplibFile) {
544 const std::string file_name{std::tmpnam(
nullptr)};
547 RoutingSolution solution = MakeTestEdgeNodeArcRoutingInstance();
548 const std::string date =
549 absl::FormatTime(
"%B %d, %E4Y", absl::Now(), absl::LocalTimeZone());
550 const std::string expected_output =
551 "Instance name: Test name\n"
552 "Authors: Based on DIMACS CARP\n"
556 "Reference: OR-Tools\n"
558 "Route #1 : 1 5-E1-11-A2-9 N9 2-E3-4-A4-1\n"
559 "Route #2 : 1-E5-12 6-E6-7 8-E7-11-E8-10-E9-1\n"
560 "Route #3 : 1 12-A10-5 3-E11-4 2-A12-3 N3 5-E13-6 1\n"
561 "Route #4 : 1 N12-E14-8-E15-10-E16-9 2-E17-1\n"
562 "Route #5 : 1 N12 N7 1\n"
564 solution.SetName(
"Test name");
565 solution.SetAuthors(
"Based on DIMACS CARP");
568 std::string written_solution;
570 EXPECT_EQ(written_solution, expected_output);
573 TEST(RoutingSolutionSerializerTest, FormatStatisticAsTsplib) {
578 TEST(RoutingSolutionSerializerTest, FormatStatisticAsCvrplib) {
583 TEST(RoutingSolutionSerializerTest, FormatStatisticAsCarplib) {
587 TEST(RoutingSolutionSerializerTest, FormatStatisticAsNearplib) {
592 TEST(RoutingSolutionSerializerTest, FormatStatisticAsTsplibLongPrecision) {
594 "STAT = 591.556557");
597 TEST(RoutingSolutionSerializerTest, FormatStatisticAsCvrplibLongPrecision) {
602 TEST(RoutingSolutionSerializerTest, FormatStatisticAsCarplibLongPrecision) {
607 TEST(RoutingSolutionSerializerTest, FormatStatisticAsNearplibLongPrecision) {
609 "STAT : 591.556557");
static RoutingSolution FromSplitRoutes(const std::vector< std::vector< int64_t >> &routes, std::optional< int64_t > depot=std::nullopt)
static std::vector< std::vector< int64_t > > SplitRoutes(const std::vector< int64_t > &solution, int64_t separator)
std::vector< Event > Route
absl::Status GetContents(const absl::string_view &filename, std::string *output, int flags)
Collection of objects used to extend the Constraint Solver library.
RoutingOutputFormat RoutingOutputFormatFromString(std::string_view format)
TEST(LinearAssignmentTest, NullMatrix)
std::string FormatStatistic(const std::string &name, T value, RoutingOutputFormat format)