22#include "absl/strings/match.h"
23#include "absl/strings/str_split.h"
24#include "absl/strings/string_view.h"
36 const double xd = from.x -
to.x;
37 const double yd = from.y -
to.y;
38 return sqrt(xd * xd + yd * yd);
43 return std::floor(DoubleEuc2DDistance(from,
to));
46constexpr double kInfinity = std::numeric_limits<double>::infinity();
48std::shared_ptr<zipfile::ZipArchive> OpenZipArchiveIfItExists(
49 absl::string_view file_name) {
50 const absl::string_view archive_name =
file::Dirname(file_name);
63 total_service_time_(0),
64 distance_function_(nullptr),
65 time_function_(nullptr) {}
68 std::shared_ptr<zipfile::ZipArchive> zip_archive(
69 OpenZipArchiveIfItExists(file_name));
71 time_windows_.clear();
72 service_times_.clear();
73 distance_matrix_.clear();
76 total_service_time_ = 0;
77 distance_function_ =
nullptr;
78 time_function_ =
nullptr;
79 return ParseLopezIbanezBlum(file_name) || ParseDaSilvaUrrutia(file_name);
82bool TspTWParser::ParseLopezIbanezBlum(absl::string_view file_name) {
85 for (
const std::string& line :
87 const std::vector<std::string> words =
88 absl::StrSplit(line, absl::ByAnyChar(
" :\t"), absl::SkipEmpty());
89 if (words.empty())
continue;
91 if (words[0] ==
"#") {
92 if (absl::StrContains(line,
"service times")) {
103 if (words.size() != 1)
return false;
105 if (size_ < 0)
return false;
106 distance_matrix_.reserve(size_ * size_);
112 if (words.size() != size_)
return false;
113 for (
const std::string& word : words) {
114 const double distance =
117 distance_matrix_.push_back(distance);
120 if (entry_count == size_) {
127 if (words.size() != 2)
return false;
128 std::vector<double> values;
129 for (
const std::string& word : words) {
133 values.push_back(value);
135 time_windows_.push_back({values[0], values[1]});
136 service_times_.push_back(0);
138 if (entry_count == size_) {
148 distance_function_ = [
this](
int from,
int to) {
149 return distance_matrix_[from * size_ +
to];
151 time_function_ = distance_function_;
152 return entry_count == size_;
155bool TspTWParser::ParseDaSilvaUrrutia(absl::string_view file_name) {
156 for (
const std::string& line :
159 if (absl::StartsWith(line,
"CUST NO."))
continue;
160 const std::vector<std::string> words =
161 absl::StrSplit(line, absl::ByAnyChar(
" :\t"), absl::SkipEmpty());
163 if (words.empty() || words[0] ==
"!!" || words[0][0] ==
'#')
continue;
164 if (words.size() != 7)
return false;
168 if (value < 0)
return false;
170 if (value == 999)
continue;
171 std::vector<double> values;
172 for (
int i = 1;
i < words.size(); ++
i) {
174 words[i], std::numeric_limits<double>::infinity());
175 if (value == std::numeric_limits<double>::infinity())
return false;
176 values.push_back(value);
178 coords_.push_back({values[0], values[1]});
179 time_windows_.push_back({values[3], values[4]});
180 service_times_.push_back(values[5]);
182 size_ = coords_.size();
185 distance_matrix_.reserve(size_ * size_);
186 for (
int i = 0;
i < size_; ++
i) {
187 for (
int j = 0; j < size_; ++j) {
188 distance_matrix_.push_back(Euc2DDistance(coords_[i], coords_[j]));
191 for (
int i = 0;
i < size_;
i++) {
192 for (
int j = 0; j < size_; j++) {
193 for (
int k = 0; k < size_; k++) {
194 if (distance_matrix_[i * size_ + j] >
195 distance_matrix_[i * size_ + k] + distance_matrix_[k * size_ + j]) {
196 distance_matrix_[
i * size_ + j] =
197 distance_matrix_[
i * size_ + k] + distance_matrix_[k * size_ + j];
203 distance_function_ = [
this](
int from,
int to) {
204 return distance_matrix_[from * size_ +
to];
206 time_function_ = [
this](
int from,
int to) {
207 return distance_matrix_[from * size_ +
to] + service_times_[from];
static int64_t FastInt64Round(double x)
double total_service_time() const
bool LoadFile(absl::string_view file_name)
absl::string_view Extension(absl::string_view path)
absl::string_view Dirname(absl::string_view path)
static constexpr double kInfinity
double ParseLeadingDoubleValue(const char *str, double deflt)
int32_t ParseLeadingInt32Value(const char *str, int32_t deflt)
std::shared_ptr< ZipArchive > OpenZipArchive(absl::string_view path, const ZipFileOptions &options)
trees with all degrees equal to