routing/parser: change namespace

This commit is contained in:
Corentin Le Molgat
2024-11-15 14:53:24 +01:00
parent 3e1ca39cc0
commit f73a92cced
35 changed files with 1394 additions and 207 deletions

View File

@@ -11,8 +11,9 @@
# See the License for the specific language governing permissions and
# limitations under the License.
load("@rules_cc//cc:defs.bzl", "cc_library", "cc_proto_library")
load("@rules_proto//proto:defs.bzl", "proto_library")
load("@com_google_protobuf//bazel:cc_proto_library.bzl", "cc_proto_library")
load("@com_google_protobuf//bazel:proto_library.bzl", "proto_library")
load("@rules_cc//cc:defs.bzl", "cc_library")
package(default_visibility = ["//visibility:public"])
@@ -59,6 +60,7 @@ cc_library(
"//ortools/base:zipfile",
"//ortools/util:filelineiter",
"@com_google_absl//absl/strings",
"@com_google_re2//:re2",
],
)
@@ -66,11 +68,15 @@ cc_test(
name = "solomon_parser_test",
size = "small",
srcs = ["solomon_parser_test.cc"],
data = ["//ortools/routing/parsers/testdata:solomon.zip"],
data = [
"//ortools/routing/parsers/testdata:c1_10_2-90-42222.96.txt",
"//ortools/routing/parsers/testdata:solomon.zip",
],
deps = [
":solomon_parser",
"//ortools/base",
"//ortools/base:file",
"//ortools/base:gmock",
"@com_google_googletest//:gtest_main",
],
)

View File

@@ -13,7 +13,11 @@
syntax = "proto3";
package operations_research;
option java_package = "com.google.ortools.routing.parser";
option java_multiple_files = true;
option csharp_namespace = "Google.OrTools.Routing.Parser";
package operations_research.routing;
// This is the proto for describing the multicommodity fixed-charged network
// design problem.

View File

@@ -21,11 +21,12 @@
#include "absl/strings/str_join.h"
#include "absl/strings/str_split.h"
#include "absl/strings/string_view.h"
#include "absl/types/span.h"
#include "ortools/base/numbers.h"
#include "ortools/util/filelineiter.h"
namespace operations_research {
namespace operations_research::routing {
CarpParser::CarpParser() { Initialize(); }
@@ -44,12 +45,12 @@ void CarpParser::Initialize() {
section_ = METADATA;
}
bool CarpParser::LoadFile(const std::string& file_name) {
bool CarpParser::LoadFile(absl::string_view file_name) {
Initialize();
return ParseFile(file_name);
}
bool CarpParser::ParseFile(const std::string& file_name) {
bool CarpParser::ParseFile(absl::string_view file_name) {
static auto section_headers = std::array<const char*, 12>({
"NOMBRE",
"COMENTARIO",
@@ -246,4 +247,4 @@ std::optional<int64_t> ParseNodeIndex(std::string_view text) {
return {node - 1};
}
} // namespace
} // namespace operations_research
} // namespace operations_research::routing

View File

@@ -60,12 +60,13 @@
#include <string_view>
#include <vector>
#include "absl/strings/string_view.h"
#include "absl/types/span.h"
#include "ortools/base/linked_hash_map.h"
#include "ortools/base/logging.h"
#include "ortools/routing/parsers/simple_graph.h"
namespace operations_research {
namespace operations_research::routing {
class CarpParser {
public:
CarpParser();
@@ -76,7 +77,7 @@ class CarpParser {
#endif
// Loads instance from a file into this parser object.
bool LoadFile(const std::string& file_name);
bool LoadFile(absl::string_view file_name);
// Returns the name of the instance being solved.
const std::string& name() const { return name_; }
@@ -156,7 +157,7 @@ class CarpParser {
};
void Initialize();
bool ParseFile(const std::string& file_name);
bool ParseFile(absl::string_view file_name);
bool ParseMetadataLine(absl::Span<const std::string> words);
bool ParseEdge(std::string_view line, bool with_servicing);
@@ -181,6 +182,6 @@ class CarpParser {
int64_t n_vehicles_;
int64_t capacity_;
};
} // namespace operations_research
} // namespace operations_research::routing
#endif // OR_TOOLS_ROUTING_PARSERS_CARP_PARSER_H_

View File

@@ -16,21 +16,14 @@
#include <string>
#include "absl/base/log_severity.h"
#include "absl/flags/flag.h"
#include "absl/log/scoped_mock_log.h"
#include "gtest/gtest.h"
#include "ortools/base/gmock.h"
#include "ortools/base/path.h"
#if defined(_MSC_VER)
#define ROOT_DIR "../../../../../../../"
#else
#define ROOT_DIR
#endif // _MSC_VER
#define ROOT_DIR "_main/"
ABSL_FLAG(std::string, test_srcdir, "", "REQUIRED: src dir");
namespace operations_research {
namespace operations_research::routing {
namespace {
TEST(CarpParserTest, Constructor) {
CarpParser parser;
@@ -69,7 +62,7 @@ TEST(CarpParserTest, LoadInvalidFileIncorrectNumberOfNodes) {
CarpParser parser;
EXPECT_FALSE(
parser.LoadFile(file::JoinPath(absl::GetFlag(FLAGS_test_srcdir), ROOT_DIR
parser.LoadFile(file::JoinPath(::testing::SrcDir(), ROOT_DIR
"ortools/routing/parsers/testdata/"
"carp_gdb19_incorrecto_vertices.dat")));
}
@@ -86,7 +79,7 @@ TEST(CarpParserTest, LoadInvalidFileIncorrectNumberOfArcsWithServicings) {
CarpParser parser;
EXPECT_FALSE(
parser.LoadFile(file::JoinPath(absl::GetFlag(FLAGS_test_srcdir), ROOT_DIR
parser.LoadFile(file::JoinPath(::testing::SrcDir(), ROOT_DIR
"ortools/routing/parsers/testdata/"
"carp_gdb19_incorrecto_arireq.dat")));
}
@@ -103,7 +96,7 @@ TEST(CarpParserTest, LoadInvalidFileIncorrectNumberOfArcsWithoutServicings) {
CarpParser parser;
EXPECT_FALSE(
parser.LoadFile(file::JoinPath(absl::GetFlag(FLAGS_test_srcdir), ROOT_DIR
parser.LoadFile(file::JoinPath(::testing::SrcDir(), ROOT_DIR
"ortools/routing/parsers/testdata/"
"carp_gdb19_incorrecto_arinoreq.dat")));
}
@@ -120,7 +113,7 @@ TEST(CarpParserTest, LoadInvalidFileIncorrectNumberOfVehicles) {
CarpParser parser;
EXPECT_FALSE(
parser.LoadFile(file::JoinPath(absl::GetFlag(FLAGS_test_srcdir), ROOT_DIR
parser.LoadFile(file::JoinPath(::testing::SrcDir(), ROOT_DIR
"ortools/routing/parsers/testdata/"
"carp_gdb19_incorrecto_vehiculos.dat")));
}
@@ -137,7 +130,7 @@ TEST(CarpParserTest, LoadInvalidFileIncorrectCapacity) {
CarpParser parser;
EXPECT_FALSE(
parser.LoadFile(file::JoinPath(absl::GetFlag(FLAGS_test_srcdir), ROOT_DIR
parser.LoadFile(file::JoinPath(::testing::SrcDir(), ROOT_DIR
"ortools/routing/parsers/testdata/"
"carp_gdb19_incorrecto_capacidad.dat")));
}
@@ -154,7 +147,7 @@ TEST(CarpParserTest, LoadInvalidFileIncorrectTypeOfArcCost) {
CarpParser parser;
EXPECT_FALSE(
parser.LoadFile(file::JoinPath(absl::GetFlag(FLAGS_test_srcdir), ROOT_DIR
parser.LoadFile(file::JoinPath(::testing::SrcDir(), ROOT_DIR
"ortools/routing/parsers/testdata/"
"carp_gdb19_incorrecto_tipo.dat")));
}
@@ -170,7 +163,7 @@ TEST(CarpParserTest, LoadInvalidFileIncorrectTotalServicingCost) {
CarpParser parser;
EXPECT_FALSE(
parser.LoadFile(file::JoinPath(absl::GetFlag(FLAGS_test_srcdir), ROOT_DIR
parser.LoadFile(file::JoinPath(::testing::SrcDir(), ROOT_DIR
"ortools/routing/parsers/testdata/"
"carp_gdb19_incorrecto_coste.dat")));
}
@@ -189,7 +182,7 @@ TEST(CarpParserTest, LoadInvalidFileIncorrectDepot) {
CarpParser parser;
EXPECT_FALSE(
parser.LoadFile(file::JoinPath(absl::GetFlag(FLAGS_test_srcdir), ROOT_DIR
parser.LoadFile(file::JoinPath(::testing::SrcDir(), ROOT_DIR
"ortools/routing/parsers/testdata/"
"carp_gdb19_incorrecto_deposito.dat")));
}
@@ -207,7 +200,7 @@ TEST(CarpParserTest, LoadInvalidFileNoEdgeWithServicing) {
CarpParser parser;
EXPECT_FALSE(parser.LoadFile(
file::JoinPath(absl::GetFlag(FLAGS_test_srcdir),
file::JoinPath(::testing::SrcDir(),
ROOT_DIR "ortools/routing/parsers"
"/testdata/carp_gdb19_no_arista_req.dat")));
}
@@ -223,7 +216,7 @@ TEST(CarpParserTest, LoadInvalidFileServicingForArcsWithoutServicing) {
CarpParser parser;
EXPECT_FALSE(
parser.LoadFile(file::JoinPath(absl::GetFlag(FLAGS_test_srcdir), ROOT_DIR
parser.LoadFile(file::JoinPath(::testing::SrcDir(), ROOT_DIR
"ortools/routing/parsers"
"/testdata/carp_gdb19_mixed_arcs.dat")));
}
@@ -239,16 +232,15 @@ TEST(CarpParserTest, LoadInvalidFileServicingForArcsInWrongOrder) {
CarpParser parser;
EXPECT_FALSE(parser.LoadFile(
file::JoinPath(absl::GetFlag(FLAGS_test_srcdir),
file::JoinPath(::testing::SrcDir(),
ROOT_DIR "ortools/routing/parsers/testdata/"
"carp_gdb19_incorrecta_lista_aristas_req.dat")));
}
TEST(CarpParserTest, LoadInstanceFile) {
std::string file_name =
file::JoinPath(absl::GetFlag(FLAGS_test_srcdir), ROOT_DIR
"ortools/routing/parsers/testdata/"
"carp_gdb19.dat");
std::string file_name = file::JoinPath(::testing::SrcDir(), ROOT_DIR
"ortools/routing/parsers/testdata/"
"carp_gdb19.dat");
CarpParser parser;
EXPECT_TRUE(parser.LoadFile(file_name));
EXPECT_EQ(parser.name(), "gdb19");
@@ -271,13 +263,12 @@ TEST(CarpParserTest, LoadInstanceFile) {
}
TEST(CarpParserTest, LoadInstanceFileWithDifferentDepot) {
std::string file_name =
file::JoinPath(absl::GetFlag(FLAGS_test_srcdir), ROOT_DIR
"ortools/routing/parsers/testdata/"
"carp_gdb19_diferente_deposito.dat");
std::string file_name = file::JoinPath(::testing::SrcDir(), ROOT_DIR
"ortools/routing/parsers/testdata/"
"carp_gdb19_diferente_deposito.dat");
CarpParser parser;
EXPECT_TRUE(parser.LoadFile(file_name));
EXPECT_EQ(parser.depot(), 4);
}
} // namespace
} // namespace operations_research
} // namespace operations_research::routing

View File

@@ -29,7 +29,7 @@
#include "ortools/routing/parsers/capacity_planning.pb.h"
#include "ortools/util/filelineiter.h"
namespace operations_research {
namespace operations_research::routing {
::absl::Status ReadFile(absl::string_view file_name,
CapacityPlanningInstance* request) {
if (!file::Exists(file_name, file::Defaults()).ok()) {
@@ -103,4 +103,4 @@ namespace operations_research {
return absl::OkStatus();
}
} // namespace operations_research
} // namespace operations_research::routing

View File

@@ -21,9 +21,9 @@
// Reader for Multicommodity fixed-charge Network Design (MCND) files using the
// .dow format.
namespace operations_research {
namespace operations_research::routing {
::absl::Status ReadFile(absl::string_view file_name,
CapacityPlanningInstance* request);
} // namespace operations_research
} // namespace operations_research::routing
#endif // OR_TOOLS_ROUTING_PARSERS_DOW_PARSER_H_

View File

@@ -15,22 +15,21 @@
#include <string>
#include "absl/flags/flag.h"
#include "absl/status/status.h"
#include "gtest/gtest.h"
#include "ortools/base/gmock.h"
#include "ortools/base/path.h"
#include "ortools/routing/parsers/capacity_planning.pb.h"
namespace operations_research {
namespace operations_research::routing {
namespace {
TEST(CapacityPlanningReaderTest, C33PassesOK) {
CapacityPlanningInstance request;
::absl::Status status = ReadFile(
file::JoinPathRespectAbsolute(
absl::GetFlag(FLAGS_test_srcdir), "operations_research_data/",
"MULTICOM_FIXED_CHARGE_NETWORK_DESIGN/C/c33.dow"),
&request);
::absl::Status status =
ReadFile(file::JoinPathRespectAbsolute(
::testing::SrcDir(), "operations_research_data/",
"MULTICOM_FIXED_CHARGE_NETWORK_DESIGN/C/c33.dow"),
&request);
EXPECT_OK(status);
const NetworkTopology& topology = request.topology();
const int num_arcs = topology.from_node_size();
@@ -48,14 +47,14 @@ TEST(CapacityPlanningReaderTest, C33PassesOK) {
TEST(CapacityPlanningReaderTest, C34DoesNotExist) {
CapacityPlanningInstance request;
::absl::Status status = ReadFile(
file::JoinPathRespectAbsolute(
absl::GetFlag(FLAGS_test_srcdir), "operations_research_data/",
"MULTICOM_FIXED_CHARGE_NETWORK_DESIGN/C/c34.dow"),
&request);
::absl::Status status =
ReadFile(file::JoinPathRespectAbsolute(
::testing::SrcDir(), "operations_research_data/",
"MULTICOM_FIXED_CHARGE_NETWORK_DESIGN/C/c34.dow"),
&request);
EXPECT_THAT(::util::StatusToString(status),
testing::HasSubstr("generic::not_found"));
}
} // namespace
} // namespace operations_research
} // namespace operations_research::routing

View File

@@ -30,7 +30,7 @@
#include "ortools/base/zipfile.h"
#include "ortools/util/filelineiter.h"
namespace operations_research {
namespace operations_research::routing {
bool LiLimParser::LoadFile(absl::string_view file_name) {
Initialize();
@@ -126,4 +126,4 @@ bool LiLimParser::ParseFile(absl::string_view file_name) {
#undef PARSE_AND_RETURN_IF_NEGATIVE
} // namespace operations_research
} // namespace operations_research::routing

View File

@@ -51,7 +51,7 @@
#include "absl/strings/string_view.h"
#include "ortools/routing/parsers/simple_graph.h"
namespace operations_research {
namespace operations_research::routing {
// Li&Lim parser class
class LiLimParser {
@@ -122,6 +122,6 @@ class LiLimParser {
std::vector<SimpleTimeWindow<int64_t>> time_windows_;
std::vector<int64_t> service_times_;
};
} // namespace operations_research
} // namespace operations_research::routing
#endif // OR_TOOLS_ROUTING_PARSERS_LILIM_PARSER_H_

View File

@@ -19,15 +19,9 @@
#include "gtest/gtest.h"
#include "ortools/base/path.h"
#if defined(_MSC_VER)
#define ROOT_DIR "../../../../../../../"
#else
#define ROOT_DIR
#endif // _MSC_VER
#define ROOT_DIR "_main/"
ABSL_FLAG(std::string, test_srcdir, "", "REQUIRED: src dir");
namespace operations_research {
namespace operations_research::routing {
namespace {
void CheckData(const LiLimParser& parser) {
@@ -55,10 +49,9 @@ TEST(LiLimParserTest, LoadNonExistingFile) {
TEST(LiLimParserTest, LoadExistingFile) {
LiLimParser parser;
EXPECT_TRUE(
parser.LoadFile(file::JoinPath(absl::GetFlag(FLAGS_test_srcdir), ROOT_DIR
"ortools/routing/parsers"
"/testdata/pdptw_LRC2_10_6.txt")));
EXPECT_TRUE(parser.LoadFile(file::JoinPath(::testing::SrcDir(), ROOT_DIR
"ortools/routing/parsers"
"/testdata/pdptw_LRC2_10_6.txt")));
CheckData(parser);
// Load a non-existing file to check the parser was cleaned.
EXPECT_FALSE(parser.LoadFile("doesnotexist.txt"));
@@ -78,12 +71,11 @@ TEST(LiLimParserTest, LoadNonExistingArchive) {
TEST(LiLimParserTest, LoadNonExistingInstance) {
LiLimParser parser;
EXPECT_FALSE(
parser.LoadFile("doesnotexist.txt",
file::JoinPath(absl::GetFlag(FLAGS_test_srcdir),
ROOT_DIR "ortools/routing/"
EXPECT_FALSE(parser.LoadFile("doesnotexist.txt",
file::JoinPath(::testing::SrcDir(), ROOT_DIR
"ortools/routing/"
"/parsers/testdata/lilim.zip")));
}
} // namespace
} // namespace operations_research
} // namespace operations_research::routing

View File

@@ -22,10 +22,11 @@
#include "absl/strings/str_join.h"
#include "absl/strings/str_split.h"
#include "absl/strings/string_view.h"
#include "ortools/base/numbers.h"
#include "ortools/util/filelineiter.h"
namespace operations_research {
namespace operations_research::routing {
NearpParser::NearpParser() { Initialize(); }
@@ -49,12 +50,12 @@ void NearpParser::Initialize() {
section_ = METADATA;
}
bool NearpParser::LoadFile(const std::string& file_name) {
bool NearpParser::LoadFile(absl::string_view file_name) {
Initialize();
return ParseFile(file_name);
}
bool NearpParser::ParseFile(const std::string& file_name) {
bool NearpParser::ParseFile(absl::string_view file_name) {
// Only put the first word as header, as the main check is just done on this
// first word (no ambiguity is possible for well-formed files; a more precise
// check is done for metadata).
@@ -357,7 +358,6 @@ std::optional<ArcOrEdge> ParseArcOrEdge(std::string_view line,
absl::StrSplit(line, absl::ByAnyChar(" :\t(),"), absl::SkipEmpty());
// Parse the name.
const std::string name = words[0];
// Parse the tail and the head of the arc/edge.
std::optional<int64_t> opt_tail = ParseNodeIndex(words[1]);
@@ -447,4 +447,4 @@ std::string NearpParser::GetEdgeName(Edge edge) const {
return absl::StrCat("NrE", edge_position - num_edges_with_servicing_ + 1);
}
}
} // namespace operations_research
} // namespace operations_research::routing

View File

@@ -80,11 +80,12 @@
#include <string_view>
#include <vector>
#include "absl/strings/string_view.h"
#include "ortools/base/linked_hash_map.h"
#include "ortools/base/logging.h"
#include "ortools/routing/parsers/simple_graph.h"
namespace operations_research {
namespace operations_research::routing {
class NearpParser {
public:
NearpParser();
@@ -95,7 +96,7 @@ class NearpParser {
#endif
// Loads instance from a file into this parser object.
bool LoadFile(const std::string& file_name);
bool LoadFile(absl::string_view file_name);
// Returns the name of the instance being solved.
const std::string& name() const { return name_; }
@@ -211,7 +212,7 @@ class NearpParser {
};
void Initialize();
bool ParseFile(const std::string& file_name);
bool ParseFile(absl::string_view file_name);
bool ParseMetadataLine(const std::vector<std::string>& words);
bool ParseArc(std::string_view line, bool with_servicing);
bool ParseEdge(std::string_view line, bool with_servicing);
@@ -252,6 +253,6 @@ class NearpParser {
int num_vehicles_;
int64_t capacity_;
};
} // namespace operations_research
} // namespace operations_research::routing
#endif // OR_TOOLS_ROUTING_PARSERS_NEARP_PARSER_H_

View File

@@ -15,20 +15,13 @@
#include <string>
#include "absl/flags/flag.h"
#include "gtest/gtest.h"
#include "ortools/base/path.h"
#include "ortools/routing/parsers/simple_graph.h"
#if defined(_MSC_VER)
#define ROOT_DIR "../../../../../../../"
#else
#define ROOT_DIR
#endif // _MSC_VER
#define ROOT_DIR "_main/"
ABSL_FLAG(std::string, test_srcdir, "", "REQUIRED: src dir");
namespace operations_research {
namespace operations_research::routing {
namespace {
TEST(NearpParserTest, Constructor) {
NearpParser parser;
@@ -55,10 +48,9 @@ TEST(NearpParserTest, LoadNonExistingFile) {
}
TEST(NearpParserTest, LoadBHW1) {
std::string file_name =
file::JoinPath(absl::GetFlag(FLAGS_test_srcdir), ROOT_DIR
"ortools/routing/parsers/testdata/"
"nearp_BHW1.dat");
std::string file_name = file::JoinPath(::testing::SrcDir(), ROOT_DIR
"ortools/routing/parsers/testdata/"
"nearp_BHW1.dat");
NearpParser parser;
EXPECT_TRUE(parser.LoadFile(file_name));
EXPECT_EQ(parser.name(), "BHW1");
@@ -97,10 +89,9 @@ TEST(NearpParserTest, LoadBHW1) {
}
TEST(NearpParserTest, LoadToy) {
std::string file_name =
file::JoinPath(absl::GetFlag(FLAGS_test_srcdir), ROOT_DIR
"ortools/routing/parsers/"
"testdata/nearp_toy.dat");
std::string file_name = file::JoinPath(::testing::SrcDir(), ROOT_DIR
"ortools/routing/parsers/"
"testdata/nearp_toy.dat");
NearpParser parser;
EXPECT_TRUE(parser.LoadFile(file_name));
EXPECT_EQ(parser.name(), "Toy");
@@ -139,4 +130,4 @@ TEST(NearpParserTest, LoadToy) {
EXPECT_EQ(parser.GetNodeName(3), "N4");
}
} // namespace
} // namespace operations_research
} // namespace operations_research::routing

View File

@@ -26,7 +26,7 @@
#include "ortools/base/strtoint.h"
#include "ortools/util/filelineiter.h"
namespace operations_research {
namespace operations_research::routing {
namespace {
using absl::ByAnyChar;
@@ -43,7 +43,7 @@ File* OpenReadOnly(absl::string_view file_name) {
PdTspParser::PdTspParser() : section_(SIZE_SECTION) {}
bool PdTspParser::LoadFile(const std::string& file_name) {
bool PdTspParser::LoadFile(absl::string_view file_name) {
for (const std::string& line :
FileLines(file_name, FileLineIterator::REMOVE_INLINE_CR)) {
ProcessNewLine(line);
@@ -104,4 +104,4 @@ void PdTspParser::ProcessNewLine(const std::string& line) {
}
}
} // namespace operations_research
} // namespace operations_research::routing

View File

@@ -22,16 +22,17 @@
#include <string>
#include <vector>
#include "absl/strings/string_view.h"
#include "ortools/base/types.h"
namespace operations_research {
namespace operations_research::routing {
class PdTspParser {
public:
PdTspParser();
~PdTspParser() = default;
// Loads and parse a PDTSP from a given file.
bool LoadFile(const std::string& file_name);
bool LoadFile(absl::string_view file_name);
// Returns the index of the depot.
int depot() const { return depot_; }
// Returns the number of nodes in the PDTSP.
@@ -54,6 +55,6 @@ class PdTspParser {
std::vector<int> deliveries_;
};
} // namespace operations_research
} // namespace operations_research::routing
#endif // OR_TOOLS_ROUTING_PARSERS_PDTSP_PARSER_H_

View File

@@ -17,19 +17,12 @@
#include <functional>
#include <string>
#include "absl/flags/flag.h"
#include "gtest/gtest.h"
#include "ortools/base/path.h"
#if defined(_MSC_VER)
#define ROOT_DIR "../../../../../../../"
#else
#define ROOT_DIR
#endif // _MSC_VER
#define ROOT_DIR "_main/"
ABSL_FLAG(std::string, test_srcdir, "", "REQUIRED: src dir");
namespace operations_research {
namespace operations_research::routing {
namespace {
TEST(PdTspParserTest, LoadDataSet) {
for (const std::string& data : {
@@ -37,8 +30,7 @@ TEST(PdTspParserTest, LoadDataSet) {
"pdtsp_prob10b.txt",
}) {
PdTspParser parser;
EXPECT_TRUE(parser.LoadFile(
file::JoinPath(absl::GetFlag(FLAGS_test_srcdir), data)));
EXPECT_TRUE(parser.LoadFile(file::JoinPath(::testing::SrcDir(), data)));
EXPECT_EQ(0, parser.depot());
EXPECT_EQ(21, parser.Size());
EXPECT_FALSE(parser.IsPickup(0)); // depot
@@ -53,4 +45,4 @@ TEST(PdTspParserTest, LoadDataSet) {
}
}
} // namespace
} // namespace operations_research
} // namespace operations_research::routing

View File

@@ -13,9 +13,9 @@
#include "ortools/routing/parsers/simple_graph.h"
namespace operations_research {
namespace operations_research::routing {
Edge::Edge(const Arc& arc) : tail_(arc.tail()), head_(arc.head()) {}
Arc::Arc(const Edge& edge) : tail_(edge.tail()), head_(edge.head()) {}
} // namespace operations_research
} // namespace operations_research::routing

View File

@@ -23,7 +23,7 @@
#include "absl/hash/hash.h"
namespace operations_research {
namespace operations_research::routing {
class Arc;
@@ -150,6 +150,6 @@ struct SimpleTimeWindow {
T end;
};
} // namespace operations_research
} // namespace operations_research::routing
#endif // OR_TOOLS_ROUTING_PARSERS_SIMPLE_GRAPH_H_

View File

@@ -19,7 +19,7 @@
#include "absl/hash/hash_testing.h"
#include "gtest/gtest.h"
namespace operations_research {
namespace operations_research::routing {
namespace {
TEST(SimpleGraphTest, EdgeHashing) {
EXPECT_TRUE(absl::VerifyTypeImplementsAbslHashCorrectly({
@@ -100,4 +100,4 @@ TEST(Coordinates3Test, Double) {
Coordinates3<double>(1.0, 2.0, 3.0)}));
}
} // namespace
} // namespace operations_research
} // namespace operations_research::routing

View File

@@ -18,25 +18,27 @@
#include <string>
#include <vector>
#include "absl/strings/ascii.h"
#include "absl/strings/match.h"
#include "absl/strings/str_join.h"
#include "absl/strings/str_split.h"
#include "absl/strings/string_view.h"
#include "ortools/base/logging.h"
#include "ortools/base/map_util.h"
#include "ortools/base/numbers.h"
#include "ortools/base/path.h"
#include "ortools/base/types.h"
#include "ortools/base/zipfile.h"
#include "ortools/util/filelineiter.h"
#include "re2/re2.h"
namespace operations_research {
namespace operations_research::routing {
SolomonParser::SolomonParser()
: sections_({{"VEHICLE", VEHICLE}, {"CUSTOMER", CUSTOMER}}) {
Initialize();
}
bool SolomonParser::LoadFile(const std::string& file_name) {
bool SolomonParser::LoadFile(absl::string_view file_name) {
Initialize();
return ParseFile(file_name);
}
@@ -67,7 +69,7 @@ void SolomonParser::Initialize() {
to_read_ = 1;
}
bool SolomonParser::ParseFile(const std::string& file_name) {
bool SolomonParser::ParseFile(absl::string_view file_name) {
for (const std::string& line :
FileLines(file_name, FileLineIterator::REMOVE_INLINE_CR)) {
const std::vector<std::string> words =
@@ -135,4 +137,46 @@ bool SolomonParser::ParseFile(const std::string& file_name) {
return section_ == CUSTOMER;
}
} // namespace operations_research
SolomonSolutionParser::SolomonSolutionParser() { Initialize(); }
bool SolomonSolutionParser::LoadFile(absl::string_view file_name) {
Initialize();
return ParseFile(file_name);
}
void SolomonSolutionParser::Initialize() {
routes_.clear();
key_values_.clear();
}
bool SolomonSolutionParser::ParseFile(absl::string_view file_name) {
bool success = false;
for (const std::string& line :
FileLines(file_name, FileLineIterator::REMOVE_INLINE_CR)) {
success = true;
const std::vector<std::string> words =
absl::StrSplit(line, ':', absl::SkipEmpty());
// Skip blank lines
if (words.empty()) continue;
std::string key = words[0];
std::string value = words.size() > 1
? absl::StrJoin(words.begin() + 1, words.end(), ":")
: "";
if (!RE2::FullMatch(key, "Route\\s*(\\d+)\\s*")) {
absl::StripAsciiWhitespace(&key);
absl::StripAsciiWhitespace(&value);
key_values_[key] = value;
// Note: the "Solution" key will be captured here. That key has no actual
// usefulness and serves as a separator before reading routes.
continue;
}
routes_.push_back(std::vector<int>());
for (const auto item :
absl::StrSplit(value, absl::ByAnyChar(" \t"), absl::SkipEmpty())) {
routes_.back().push_back(strings::ParseLeadingInt32Value(item, -1));
}
}
return success;
}
} // namespace operations_research::routing

View File

@@ -49,12 +49,11 @@
#include <string>
#include <vector>
#include "absl/container/flat_hash_map.h"
#include "absl/strings/string_view.h"
#include "ortools/base/macros.h"
#include "ortools/base/types.h"
#include "ortools/routing/parsers/simple_graph.h"
namespace operations_research {
namespace operations_research::routing {
// Solomon parser class.
class SolomonParser {
@@ -70,7 +69,7 @@ class SolomonParser {
// the instance. Loading a new instance clears the previously loaded instance.
// Loads instance from a file.
bool LoadFile(const std::string& file_name);
bool LoadFile(absl::string_view file_name);
// Loads instance from a file contained in a zipped archive; the archive can
// contain multiple files.
bool LoadFile(absl::string_view file_name, const std::string& archive_name);
@@ -115,7 +114,7 @@ class SolomonParser {
// Parsing
void Initialize();
bool ParseFile(const std::string& file_name);
bool ParseFile(absl::string_view file_name);
// Parsing data
const std::map<std::string, Section> sections_;
@@ -134,6 +133,45 @@ class SolomonParser {
std::vector<SimpleTimeWindow<int64_t>> time_windows_;
std::vector<int64_t> service_times_;
};
} // namespace operations_research
// Solomon solution parser class.
class SolomonSolutionParser {
public:
SolomonSolutionParser();
#ifndef SWIG
SolomonSolutionParser(const SolomonSolutionParser&) = delete;
const SolomonSolutionParser& operator=(const SolomonSolutionParser&) = delete;
#endif
// Loads solution from a file. Returns false in case of failure to read
// the file. Loading a new solution clears the previously loaded solution.
bool LoadFile(absl::string_view file_name);
// Returns the number of routes used in the solution.
int NumberOfRoutes() const { return routes_.size(); }
// Returns the sequence of the ith route, excluding depot nodes.
const std::vector<int>& route(int i) const { return routes_[i]; }
// Returns the value corresponding to a key. Keys can be (but are not limited
// to) "Authors", "Date", "Instance Name", or "Reference". These keys might
// vary slightly per instance (refer to the input file).
const std::string& GetValueFromKey(absl::string_view key) const {
static const std::string* default_value = new std::string{};
auto it = key_values_.find(key);
if (it != key_values_.end()) return it->second;
return *default_value;
}
private:
// Parsing
void Initialize();
bool ParseFile(absl::string_view file_name);
// Parsing data
std::vector<std::vector<int>> routes_;
absl::flat_hash_map<std::string, std::string> key_values_;
};
} // namespace operations_research::routing
#endif // OR_TOOLS_ROUTING_PARSERS_SOLOMON_PARSER_H_

View File

@@ -18,9 +18,10 @@
#include "absl/flags/flag.h"
#include "gtest/gtest.h"
#include "ortools/base/commandlineflags.h"
#include "ortools/base/gmock.h"
#include "ortools/base/path.h"
ABSL_FLAG(std::string, test_srcdir, "", "REQUIRED: src dir");
#define ROOT_DIR "_main/"
ABSL_FLAG(std::string, solomon_test_archive,
"ortools/bench/solomon/"
@@ -29,7 +30,7 @@ ABSL_FLAG(std::string, solomon_test_archive,
ABSL_FLAG(std::string, solomon_test_instance, "google2.txt",
"Solomon: testing instance");
namespace operations_research {
namespace operations_research::routing {
namespace {
TEST(SolomonParserTest, LoadEmptyFileName) {
std::string empty_file_name;
@@ -58,8 +59,40 @@ TEST(SolomonParserTest, LoadNonExistingInstance) {
SolomonParser parser;
EXPECT_FALSE(parser.LoadFile(
"doesnotexist.txt",
file::JoinPath(absl::GetFlag(FLAGS_test_srcdir),
file::JoinPath(::testing::SrcDir(),
absl::GetFlag(FLAGS_solomon_test_archive))));
}
TEST(SolomonSolutionParserTest, LoadEmptyFileName) {
std::string empty_file_name;
SolomonSolutionParser parser;
EXPECT_FALSE(parser.LoadFile(empty_file_name));
}
TEST(SolomonSolutionParserTest, LoadNonExistingFile) {
SolomonSolutionParser parser;
EXPECT_FALSE(parser.LoadFile(""));
}
TEST(SolomonSolutionParserTest, LoadFile) {
SolomonSolutionParser parser;
EXPECT_TRUE(parser.LoadFile(file::JoinPath(::testing::SrcDir(), ROOT_DIR
"ortools/routing/parsers/testdata/"
"c1_10_2-90-42222.96.txt")));
EXPECT_EQ(parser.NumberOfRoutes(), 90);
EXPECT_EQ(parser.GetValueFromKey("Instance Name"), "c1_10_2");
EXPECT_EQ(
parser.GetValueFromKey("Authors"),
"Zhu He, Longfei Wang, Weibo Lin, Yujie Chen, Haoyuan Hu "
"(haoyuan.huhy@cainiao.com), Yinghui Xu & VRP Team (Ying Zhang, Guotao "
"Wu, Kunpeng Han et al.), unpublished result of CAINIAO AI.");
EXPECT_EQ(parser.GetValueFromKey("Date"), "05-10-2018");
EXPECT_EQ(parser.GetValueFromKey("Reference"),
"\"New Algorithm for VRPTW\", unpublished result of CAINIAO AI.");
EXPECT_EQ(parser.GetValueFromKey("NonExistingKey"), "");
EXPECT_THAT(parser.route(0), ::testing::ElementsAre(1, 987, 466, 279, 31, 276,
263, 207, 646, 193, 3));
}
} // namespace
} // namespace operations_research
} // namespace operations_research::routing

View File

@@ -25,7 +25,7 @@
#include "absl/types/span.h"
#include "ortools/base/logging.h"
namespace operations_research {
namespace operations_research::routing {
RoutingOutputFormat RoutingOutputFormatFromString(std::string_view format) {
const std::string format_normalized =
@@ -45,7 +45,7 @@ std::vector<RoutingSolution::Route> RoutesFromVector(
} // namespace
std::vector<std::vector<int64_t>> RoutingSolution::SplitRoutes(
const std::vector<int64_t>& solution, int64_t separator) {
absl::Span<const int64_t> solution, int64_t separator) {
// The solution vector separates routes by -1: split this vector into a vector
// per route, where the other helpers can make the rest of the way to a proper
// RoutingSolution object.
@@ -384,7 +384,7 @@ std::string SerializeRouteToCVRPLIBString(const RoutingSolution::Route& route) {
// Before serializing the route, make some tests to check that the hypotheses
// are respected (otherwise, the output of the function is highly likely
// pure garbage).
RoutingSolution::Event first_event = route[0];
const RoutingSolution::Event& first_event = route[0];
CHECK(first_event.type == RoutingSolution::Event::Type::kStart)
<< "The route does not begin with a Start event to indicate "
"the depot.";
@@ -397,7 +397,7 @@ std::string SerializeRouteToCVRPLIBString(const RoutingSolution::Route& route) {
std::string current_route;
for (int64_t i = 1; i < route.size() - 1; ++i) {
RoutingSolution::Event event = route[i];
const RoutingSolution::Event& event = route[i];
// Ignore the depot, as CVRPLIB doesn't output the depot in the routes
// (all routes implicitly start and end at the depot).
@@ -410,7 +410,7 @@ std::string SerializeRouteToCVRPLIBString(const RoutingSolution::Route& route) {
// Last event: end at a depot. Due to the strange way CVRPLIB
// outputs nodes, the depot must be the same at the beginning and the
// end of the route.
RoutingSolution::Event last_event = route.back();
const RoutingSolution::Event& last_event = route.back();
if (last_event.type == RoutingSolution::Event::Type::kEnd) {
CHECK_EQ(depot, last_event.arc.tail());
CHECK_EQ(last_event.arc.tail(), last_event.arc.head());
@@ -422,4 +422,4 @@ std::string SerializeRouteToCVRPLIBString(const RoutingSolution::Route& route) {
return current_route;
}
} // namespace
} // namespace operations_research
} // namespace operations_research::routing

View File

@@ -32,7 +32,7 @@
#include "ortools/base/logging.h"
#include "ortools/routing/parsers/simple_graph.h"
namespace operations_research {
namespace operations_research::routing {
// Indicates the format in which the output should be done. This enumeration is
// used for solutions and solver statistics.
@@ -137,7 +137,7 @@ class RoutingSolution {
// (TSPLIB uses -1; it is crucial that the separator cannot be a node) into
// a vector per route, for use in FromSplit* functions.
static std::vector<std::vector<int64_t>> SplitRoutes(
const std::vector<int64_t>& solution, int64_t separator);
absl::Span<const int64_t> solution, int64_t separator);
// Builds a RoutingSolution object from a vector of routes, each represented
// as a vector of nodes being traversed. All the routes are supposed to start
@@ -291,6 +291,6 @@ void PrintStatistic(absl::string_view name, T value,
RoutingOutputFormat format) {
absl::PrintF("%s\n", FormatStatistic(name, value, format));
}
} // namespace operations_research
} // namespace operations_research::routing
#endif // OR_TOOLS_ROUTING_PARSERS_SOLUTION_SERIALIZER_H_

View File

@@ -28,7 +28,7 @@
#include "ortools/base/options.h"
#include "ortools/routing/parsers/simple_graph.h"
namespace operations_research {
namespace operations_research::routing {
namespace {
using testing::MatchesRegex;
@@ -629,4 +629,4 @@ TEST(RoutingSolutionSerializerTest, FormatStatisticAsNearplibLongPrecision) {
"STAT : 591.556557");
}
} // namespace
} // namespace operations_research
} // namespace operations_research::routing

View File

@@ -12,6 +12,7 @@
# limitations under the License.
exports_files([
"c1_10_2-90-42222.96.txt",
"carp_gdb19.dat", # https://github.com/vidalt/HGS-CARP/blob/master/Instances/CARP/gdb19.dat
# https://www.sciencedirect.com/science/article/abs/pii/0305054883900266
"carp_gdb19_diferente_deposito.dat",

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,95 @@
Instance Name: c1_10_2
Authors: Zhu He, Longfei Wang, Weibo Lin, Yujie Chen, Haoyuan Hu (haoyuan.huhy@cainiao.com), Yinghui Xu & VRP Team (Ying Zhang, Guotao Wu, Kunpeng Han et al.), unpublished result of CAINIAO AI.
Date: 05-10-2018
Reference: "New Algorithm for VRPTW", unpublished result of CAINIAO AI.
Solution
Route 1 : 1 987 466 279 31 276 263 207 646 193 3
Route 2 : 854 783 861 166 515 307 687 617 496 70
Route 3 : 28 775 973 188 527 245 793 636 147 747 547
Route 4 : 35 825 932 868 154 370 827 832 270 171 146
Route 5 : 36 714 945 20 46 703 493 610 23 524 968
Route 6 : 38 633 262 63 618 632 366 192 12 929 988
Route 7 : 54 483 531 334 100 414 430 326 550 802 853 447
Route 8 : 66 545 557 381 271 215 630 264 750 834 95
Route 9 : 76 631 467 333 639 229 730 88 659 110 42
Route 10 : 79 664 49 489 490 16 669 731 375 701 436 387
Route 11 : 106 158 81 385 537 124 816 412 160
Route 12 : 108 182 470 93 203 716 706 875 693 762 601 232 165
Route 13 : 115 962 486 743 440 512 397 939 123 494 549
Route 14 : 116 563 986 938 818 27 189 174 522 886 862 880 441
Route 15 : 122 777 564 320 301 763 360 236 80 642 310
Route 16 : 130 725 612 904 855 13 794 971 628 438 498 561 663
Route 17 : 164 323 242 419 622 942 885 609 877 290 753
Route 18 : 167 84 867 779 908 595 468 847 916 194 41
Route 19 : 175 144 551 94 913 539 891 892 507 133 692 373
Route 20 : 183 745 218 371 643 143 844 956 661
Route 21 : 184 139 955 14 645 754 700 889 195
Route 22 : 190 842 50 596 830 872 903 459 822 675 984
Route 23 : 208 425 149 332 851 134 409 358 978 671 936 739
Route 24 : 212 859 324 421 369 261 838 697 814 327
Route 25 : 238 597 287 772 506 626 471 260 376 817
Route 26 : 244 896 200 846 634 624 201 445 517 454 92 764
Route 27 : 278 511 308 424 90 395 77 728 65 519 186
Route 28 : 285 736 34 922 61 744 911 680 153
Route 29 : 306 479 437 719 177 607 769 135 724 379 525 791
Route 30 : 309 890 602 721 253 651 11 829 523 250 435
Route 31 : 328 879 501 683 344 426 799 594 503 399 98 82 156
Route 32 : 336 508 254 152 112 157 29 757 101 392 453 860 283 221
Route 33 : 351 682 475 852 428 907 429 749 235 127 382 460
Route 34 : 363 45 68 575 295 180 302 187 19 580 833
Route 35 : 364 492 219 170 240 216 349 178 237 176
Route 36 : 380 44 4 17 18 105 811 943 723 297 695 778
Route 37 : 386 792 901 909 259 319 145 803 128 691 668 874 173
Route 38 : 388 760 151 137 998 163 26 665 340 756 504
Route 39 : 394 813 840 463 586 906 541 138 905 225 946 249
Route 40 : 402 766 343 930 921 989 917 677 931
Route 41 : 406 820 502 222 927 509 465 196 674 871 662
Route 42 : 415 322 627 461 47 773 389 603 977 593
Route 43 : 451 605 578 457 748 325 673 735 637 848 647 99
Route 44 : 473 109 40 282 298 119 821 491 383 150 129
Route 45 : 482 625 990 584 60 809 993 864 790 280 43 797
Route 46 : 487 255 899 289 572 950 423 85 554 233 881 650 458
Route 47 : 532 33 209 709 991 372 894 672 641
Route 48 : 535 303 226 345 897 202 210 118
Route 49 : 536 257 121 966 635 247 113 452 448 367 347 83 500
Route 50 : 562 148 291 57 131 559 172 569 698 462 678 513
Route 51 : 570 350 882 400 752 269 97 919 666 9 89 356 689
Route 52 : 571 681 948 91 96 378 275 865 75 713 185 431
Route 53 : 577 533 329 393 967 474 688 315 472 518 411
Route 54 : 581 933 52 335 368 654 918 530 444 699 59 140
Route 55 : 6 268 980 574 206 427 67 339 231 495 420 590
Route 56 : 611 940 534 738 117 768 657 863 330 248 826 162
Route 57 : 616 313 481 74 876 795 114 338 895 416 284 805 878 234
Route 58 : 599 755 704 798 10 649 556 273 717 566
Route 59 : 638 72 573 337 613 947 588 439 751
Route 60 : 648 949 197 767 214 198 64 589 243
Route 61 : 652 823 258 317 958 505 142 516 341 606
Route 62 : 655 976 629 807 314 141 239 220 55 883
Route 63 : 660 294 321 353 983 499 348 548 405 272
Route 64 : 667 808 926 191 712 898 979 915 732 544 488
Route 65 : 705 316 600 870 786 274 390 352 869
Route 66 : 711 403 970 729 413 866 887 408 690 812 614 845
Route 67 : 722 718 432 727 288 835 858 361 839 608 994 384
Route 68 : 780 529 300 740 37 292 696 205 746 514 204 582 965
Route 69 : 784 708 497 48 935 484 653 975 434 765 964
Route 70 : 785 267 837 104 132 925 526 223 24 217 568 640
Route 71 : 789 553 103 331 972 974 422 944 401 579 538 78
Route 72 : 815 658 656 771 761 168 592 464 281 391
Route 73 : 819 999 246 742 781 953 560 418 159 374 417
Route 74 : 836 293 542 928 952 446 396 733 15 73 741 469 694
Route 75 : 849 476 788 528 354 555 342 558 685 552 346 7 443
Route 76 : 623 734 228 107 776 992 598 951
Route 77 : 856 758 774 478 410 5 477 398 286
Route 78 : 902 543 679 604 8 920 227 850 828 433 567 161 71
Route 79 : 914 362 621 969 213 251 455 252 86 485
Route 80 : 923 800 211 359 442 804 715 311 893 266
Route 81 : 924 155 224 312 702 199 737 21 583 87 365 521
Route 82 : 937 181 407 102 934 720 126 265 2 53 62 912 910
Route 83 : 941 32 520 357 686 644 25 136 900 1000
Route 84 : 957 787 806 710 318 831 450 587 961 58 179 843
Route 85 : 960 810 620 959 841 304 480 684 56 770 591 51
Route 86 : 963 726 801 456 565 670 241 230 169 540
Route 87 : 981 125 954 404 39 782 256 857 510 22
Route 88 : 982 707 111 759 377 296 995 546 449 299 619
Route 89 : 985 884 305 30 277 888 824 355 615
Route 90 : 997 69 585 796 120 996 873 576 676

View File

@@ -36,7 +36,7 @@
#include "ortools/util/filelineiter.h"
#include "re2/re2.h"
namespace operations_research {
namespace operations_research::routing {
namespace {
// ----- Distances -----
@@ -171,7 +171,7 @@ TspLibParser::TspLibParser()
edge_column_(0),
to_read_(0) {}
bool TspLibParser::LoadFile(const std::string& file_name) {
bool TspLibParser::LoadFile(absl::string_view file_name) {
std::shared_ptr<zipfile::ZipArchive> zip_archive(
OpenZipArchiveIfItExists(file_name));
for (const std::string& line :
@@ -182,7 +182,7 @@ bool TspLibParser::LoadFile(const std::string& file_name) {
return true;
}
int TspLibParser::SizeFromFile(const std::string& file_name) const {
int TspLibParser::SizeFromFile(absl::string_view file_name) const {
std::shared_ptr<zipfile::ZipArchive> zip_archive(
OpenZipArchiveIfItExists(file_name));
int size = 0;
@@ -747,7 +747,7 @@ TspLibTourParser::TspLibTourParser() : section_(UNDEFINED_SECTION), size_(0) {}
// TODO(user): Return false when issues were encountered while parsing the
// file.
bool TspLibTourParser::LoadFile(const std::string& file_name) {
bool TspLibTourParser::LoadFile(absl::string_view file_name) {
section_ = UNDEFINED_SECTION;
comments_.clear();
tour_.clear();
@@ -818,7 +818,7 @@ CVRPToursParser::CVRPToursParser() : cost_(0) {}
// TODO(user): Return false when issues were encountered while parsing the
// file.
bool CVRPToursParser::LoadFile(const std::string& file_name) {
bool CVRPToursParser::LoadFile(absl::string_view file_name) {
tours_.clear();
cost_ = 0;
std::shared_ptr<zipfile::ZipArchive> zip_archive(
@@ -852,4 +852,4 @@ void CVRPToursParser::ProcessNewLine(const std::string& line) {
}
}
} // namespace operations_research
} // namespace operations_research::routing

View File

@@ -31,11 +31,12 @@
#include <vector>
#include "absl/container/flat_hash_map.h"
#include "absl/strings/string_view.h"
#include "absl/types/span.h"
#include "ortools/base/types.h"
#include "ortools/routing/parsers/simple_graph.h"
namespace operations_research {
namespace operations_research::routing {
class TspLibParser final {
public:
@@ -44,9 +45,9 @@ class TspLibParser final {
TspLibParser();
// Loads and parses a routing problem from a given file.
bool LoadFile(const std::string& file_name);
bool LoadFile(absl::string_view file_name);
// Returns the number of nodes in the routing problem stored in a given file.
int SizeFromFile(const std::string& file_name) const;
int SizeFromFile(absl::string_view file_name) const;
// Returns a function returning edge weights between nodes.
EdgeWeights GetEdgeWeights() const { return distance_function_; }
// Returns the index of the depot.
@@ -197,7 +198,7 @@ class TspLibTourParser final {
public:
TspLibTourParser();
// Loads and parses a given tour file.
bool LoadFile(const std::string& file_name);
bool LoadFile(absl::string_view file_name);
// Returns a vector corresponding to the sequence of nodes of the tour.
const std::vector<int>& tour() const { return tour_; }
// Returns the size of the tour.
@@ -236,7 +237,7 @@ class CVRPToursParser final {
public:
CVRPToursParser();
// Loads and parses a given tours file.
bool LoadFile(const std::string& file_name);
bool LoadFile(absl::string_view file_name);
// Returns a vector corresponding to the sequence of nodes of tours.
const std::vector<std::vector<int>>& tours() const { return tours_; }
int64_t cost() const { return cost_; }
@@ -247,6 +248,6 @@ class CVRPToursParser final {
std::vector<std::vector<int>> tours_;
int64_t cost_;
};
} // namespace operations_research
} // namespace operations_research::routing
#endif // OR_TOOLS_ROUTING_PARSERS_TSPLIB_PARSER_H_

View File

@@ -21,7 +21,6 @@
#include "absl/base/macros.h"
#include "absl/container/btree_set.h"
#include "absl/flags/flag.h"
#include "absl/strings/str_format.h"
#include "absl/strings/string_view.h"
#include "gtest/gtest.h"
@@ -31,15 +30,9 @@
#include "ortools/base/path.h"
#include "ortools/base/zipfile.h"
#if defined(_MSC_VER)
#define ROOT_DIR "../../../../../../../"
#else
#define ROOT_DIR
#endif // _MSC_VER
#define ROOT_DIR "_main/"
ABSL_FLAG(std::string, test_srcdir, "", "REQUIRED: src dir");
namespace operations_research {
namespace operations_research::routing {
namespace {
TEST(TspLibParserTest, GeneratedDataSets) {
@@ -251,8 +244,8 @@ TEST(TspLibParserTest, ParseHCPAdjList) {
TEST(TspLibParserTest, ParseKytojoki33Depot) {
// This file inverts EDGE_WEIGHT_TYPE and EDGE_WEIGHT_FORMAT.
std::string file_name = file::JoinPath(
absl::GetFlag(FLAGS_test_srcdir),
ROOT_DIR "ortools/routing/parsers/testdata/", "tsplib_Kytojoki_33.vrp");
::testing::SrcDir(), ROOT_DIR "ortools/routing/parsers/testdata/",
"tsplib_Kytojoki_33.vrp");
TspLibParser parser;
EXPECT_TRUE(parser.LoadFile(file_name));
// The depot is a new node, given by its coordinates, instead of an existing
@@ -301,8 +294,8 @@ TEST(TspLibTourParserTest, LoadAllDataSets) {
": Optimal solution of ulysses22 (7013)"};
int file_index = 0;
std::vector<std::string> matches;
if (file::Match(file::JoinPath("/tarfs", absl::GetFlag(FLAGS_test_srcdir),
kArchive, "*\\.opt\\.tour\\.gz"),
if (file::Match(file::JoinPath("/tarfs", ::testing::SrcDir(), kArchive,
"*\\.opt\\.tour\\.gz"),
&matches, file::Defaults())
.ok()) {
for (const std::string& match : matches) {
@@ -336,9 +329,9 @@ TEST(CVRPToursParserTest, LoadAllDataSets) {
/*opt-A-n55-k9*/ 1073};
int file_index = 0;
std::vector<std::string> matches;
if (file::Match(file::JoinPath("/zip", absl::GetFlag(FLAGS_test_srcdir),
kArchive, "opt-A-\\.*"),
&matches, file::Defaults())
if (file::Match(
file::JoinPath("/zip", ::testing::SrcDir(), kArchive, "opt-A-\\.*"),
&matches, file::Defaults())
.ok()) {
for (const std::string& match : matches) {
CVRPToursParser parser;
@@ -349,4 +342,4 @@ TEST(CVRPToursParserTest, LoadAllDataSets) {
}
}
} // namespace
} // namespace operations_research
} // namespace operations_research::routing

View File

@@ -29,7 +29,7 @@
#include "ortools/base/zipfile.h"
#include "ortools/util/filelineiter.h"
namespace operations_research {
namespace operations_research::routing {
namespace {
@@ -66,7 +66,7 @@ TspTWParser::TspTWParser()
distance_function_(nullptr),
time_function_(nullptr) {}
bool TspTWParser::LoadFile(const std::string& file_name) {
bool TspTWParser::LoadFile(absl::string_view file_name) {
std::shared_ptr<zipfile::ZipArchive> zip_archive(
OpenZipArchiveIfItExists(file_name));
coords_.clear();
@@ -81,7 +81,7 @@ bool TspTWParser::LoadFile(const std::string& file_name) {
return ParseLopezIbanezBlum(file_name) || ParseDaSilvaUrrutia(file_name);
}
bool TspTWParser::ParseLopezIbanezBlum(const std::string& file_name) {
bool TspTWParser::ParseLopezIbanezBlum(absl::string_view file_name) {
int section = 0;
int entry_count = 0;
for (const std::string& line :
@@ -154,7 +154,7 @@ bool TspTWParser::ParseLopezIbanezBlum(const std::string& file_name) {
return entry_count == size_;
}
bool TspTWParser::ParseDaSilvaUrrutia(const std::string& file_name) {
bool TspTWParser::ParseDaSilvaUrrutia(absl::string_view file_name) {
for (const std::string& line :
FileLines(file_name, FileLineIterator::REMOVE_INLINE_CR)) {
// Skip header.
@@ -211,4 +211,4 @@ bool TspTWParser::ParseDaSilvaUrrutia(const std::string& file_name) {
return true;
}
} // namespace operations_research
} // namespace operations_research::routing

View File

@@ -25,16 +25,17 @@
#include <string>
#include <vector>
#include "absl/strings/string_view.h"
#include "ortools/base/types.h"
#include "ortools/routing/parsers/simple_graph.h"
namespace operations_research {
namespace operations_research::routing {
class TspTWParser final {
public:
TspTWParser();
// Loads and parses a routing problem from a given file.
bool LoadFile(const std::string& file_name);
bool LoadFile(absl::string_view file_name);
// Returns a function returning the distance between nodes. On some instances
// service times are already included in values returned by this function.
// The actual distance of a route can be obtained by removing
@@ -69,8 +70,8 @@ class TspTWParser final {
TspTWParser(const TspTWParser&) = delete;
void operator=(const TspTWParser&) = delete;
#endif
bool ParseLopezIbanezBlum(const std::string& file_name);
bool ParseDaSilvaUrrutia(const std::string& file_name);
bool ParseLopezIbanezBlum(absl::string_view file_name);
bool ParseDaSilvaUrrutia(absl::string_view file_name);
int64_t size_;
int depot_;
@@ -83,6 +84,6 @@ class TspTWParser final {
std::vector<double> distance_matrix_;
};
} // namespace operations_research
} // namespace operations_research::routing
#endif // OR_TOOLS_ROUTING_PARSERS_TSPTW_PARSER_H_

View File

@@ -15,19 +15,12 @@
#include <string>
#include "absl/flags/flag.h"
#include "gtest/gtest.h"
#include "ortools/base/path.h"
#if defined(_MSC_VER)
#define ROOT_DIR "../../../../../../../"
#else
#define ROOT_DIR
#endif // _MSC_VER
#define ROOT_DIR "_main/"
ABSL_FLAG(std::string, test_srcdir, "", "REQUIRED: src dir");
namespace operations_research {
namespace operations_research::routing {
namespace {
TEST(TspTWParserTest, LoadDataSet) {
@@ -46,8 +39,7 @@ TEST(TspTWParserTest, LoadDataSet) {
ROOT_DIR "ortools/routing/parsers/testdata/"
"n20w20.002.txt"}) {
TspTWParser parser;
EXPECT_TRUE(parser.LoadFile(
file::JoinPath(absl::GetFlag(FLAGS_test_srcdir), data)));
EXPECT_TRUE(parser.LoadFile(file::JoinPath(::testing::SrcDir(), data)));
EXPECT_EQ(0, parser.depot());
const int size = sizes[count];
EXPECT_EQ(size, parser.size());
@@ -77,4 +69,4 @@ TEST(TspTWParserTest, LoadDataSet) {
}
} // namespace
} // namespace operations_research
} // namespace operations_research::routing