22 #include "absl/strings/match.h"
23 #include "absl/strings/str_split.h"
35 double DoubleEuc2DDistance(
const Coordinates2<double>& from,
36 const Coordinates2<double>& to) {
37 const double xd = from.x - to.x;
38 const double yd = from.y - to.y;
39 return sqrt(xd * xd + yd * yd);
42 double Euc2DDistance(
const Coordinates2<double>& from,
43 const Coordinates2<double>& to) {
44 return std::floor(DoubleEuc2DDistance(from, to));
47 constexpr
double kInfinity = std::numeric_limits<double>::infinity();
49 std::shared_ptr<zipfile::ZipArchive> OpenZipArchiveIfItExists(
50 const std::string& file_name) {
51 const absl::string_view archive_name =
file::Dirname(file_name);
64 total_service_time_(0),
65 distance_function_(nullptr),
66 time_function_(nullptr) {}
69 std::shared_ptr<zipfile::ZipArchive> zip_archive(
70 OpenZipArchiveIfItExists(file_name));
72 time_windows_.clear();
73 service_times_.clear();
74 distance_matrix_.clear();
77 total_service_time_ = 0;
78 distance_function_ =
nullptr;
79 time_function_ =
nullptr;
80 return ParseLopezIbanezBlum(file_name) || ParseDaSilvaUrrutia(file_name);
83 bool TspTWParser::ParseLopezIbanezBlum(
const std::string& file_name) {
86 for (
const std::string&
line :
88 const std::vector<std::string> words =
89 absl::StrSplit(
line, absl::ByAnyChar(
" :\t"), absl::SkipEmpty());
90 if (words.empty())
continue;
92 if (words[0] ==
"#") {
93 if (absl::StrContains(
line,
"service times")) {
104 if (words.size() != 1)
return false;
106 if (size_ < 0)
return false;
107 distance_matrix_.reserve(size_ * size_);
113 if (words.size() != size_)
return false;
114 for (
const std::string& word : words) {
118 distance_matrix_.push_back(
distance);
121 if (entry_count == size_) {
128 if (words.size() != 2)
return false;
129 std::vector<double> values;
130 for (
const std::string& word : words) {
134 values.push_back(
value);
136 time_windows_.push_back({values[0], values[1]});
137 service_times_.push_back(0);
139 if (entry_count == size_) {
149 distance_function_ = [
this](
int from,
int to) {
150 return distance_matrix_[from * size_ + to];
152 time_function_ = distance_function_;
153 return entry_count == size_;
156 bool TspTWParser::ParseDaSilvaUrrutia(
const std::string& file_name) {
157 for (
const std::string&
line :
160 if (absl::StartsWith(
line,
"CUST NO."))
continue;
161 const std::vector<std::string> words =
162 absl::StrSplit(
line, absl::ByAnyChar(
" :\t"), absl::SkipEmpty());
164 if (words.empty() || words[0] ==
"!!" || words[0][0] ==
'#')
continue;
165 if (words.size() != 7)
return false;
169 if (
value < 0)
return false;
171 if (
value == 999)
continue;
172 std::vector<double> values;
173 for (
int i = 1; i < words.size(); ++i) {
175 words[i], std::numeric_limits<double>::infinity());
176 if (
value == std::numeric_limits<double>::infinity())
return false;
177 values.push_back(
value);
179 coords_.push_back({values[0], values[1]});
180 time_windows_.push_back({values[3], values[4]});
181 service_times_.push_back(values[5]);
183 size_ = coords_.size();
186 distance_matrix_.reserve(size_ * size_);
187 for (
int i = 0; i < size_; ++i) {
188 for (
int j = 0; j < size_; ++j) {
189 distance_matrix_.push_back(Euc2DDistance(coords_[i], coords_[j]));
192 for (
int i = 0; i < size_; i++) {
193 for (
int j = 0; j < size_; j++) {
194 for (
int k = 0; k < size_; k++) {
195 if (distance_matrix_[i * size_ + j] >
196 distance_matrix_[i * size_ + k] + distance_matrix_[k * size_ + j]) {
197 distance_matrix_[i * size_ + j] =
198 distance_matrix_[i * size_ + k] + distance_matrix_[k * size_ + j];
204 distance_function_ = [
this](
int from,
int to) {
205 return distance_matrix_[from * size_ + to];
207 time_function_ = [
this](
int from,
int to) {
208 return distance_matrix_[from * size_ + to] + service_times_[from];
static int64_t FastInt64Round(double x)
double total_service_time() const
bool LoadFile(const std::string &file_name)
absl::string_view Dirname(absl::string_view path)
absl::string_view Extension(absl::string_view path)
Collection of objects used to extend the Constraint Solver library.
int32_t ParseLeadingInt32Value(const char *str, int32_t deflt)
double ParseLeadingDoubleValue(const char *str, double deflt)
std::shared_ptr< ZipArchive > OpenZipArchive(absl::string_view path, const ZipFileOptions &options)
constexpr double kInfinity