123 lines
3.3 KiB
C++
123 lines
3.3 KiB
C++
// Copyright 2010-2022 Google LLC
|
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
// you may not use this file except in compliance with the License.
|
|
// You may obtain a copy of the License at
|
|
//
|
|
// http://www.apache.org/licenses/LICENSE-2.0
|
|
//
|
|
// Unless required by applicable law or agreed to in writing, software
|
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
// See the License for the specific language governing permissions and
|
|
// limitations under the License.
|
|
|
|
#include "ortools/packing/vector_bin_packing_parser.h"
|
|
|
|
#include <cstdint>
|
|
#include <string>
|
|
|
|
#include "absl/strings/numbers.h"
|
|
#include "absl/strings/str_split.h"
|
|
#include "ortools/packing/vector_bin_packing.pb.h"
|
|
#include "ortools/util/filelineiter.h"
|
|
|
|
namespace operations_research {
|
|
namespace packing {
|
|
namespace vbp {
|
|
|
|
bool VbpParser::ParseFile(const std::string& data_filename) {
|
|
vbp_.Clear();
|
|
|
|
load_status_ = DIMENSION_SECTION;
|
|
for (const std::string& line : FileLines(data_filename)) {
|
|
if (load_status_ == ERROR_FOUND) break;
|
|
ProcessLine(line);
|
|
}
|
|
|
|
// Checks status.
|
|
if (load_status_ == ERROR_FOUND) {
|
|
LOG(INFO) << vbp_.DebugString();
|
|
return false;
|
|
}
|
|
return vbp_.item_size() == num_declared_items_;
|
|
}
|
|
|
|
void VbpParser::ReportError(const std::string& line) {
|
|
LOG(ERROR) << "Error: status = " << load_status_ << ", line = " << line;
|
|
load_status_ = ERROR_FOUND;
|
|
}
|
|
|
|
void VbpParser::ProcessLine(const std::string& line) {
|
|
const std::vector<std::string> words =
|
|
absl::StrSplit(line, absl::ByAnyChar(" :\t\r"), absl::SkipEmpty());
|
|
|
|
if (words.empty()) return;
|
|
|
|
switch (load_status_) {
|
|
case NOT_STARTED: {
|
|
LOG(FATAL) << "Should not be here";
|
|
}
|
|
case DIMENSION_SECTION: {
|
|
if (words.size() != 1) {
|
|
ReportError(line);
|
|
return;
|
|
}
|
|
num_resources_ = strtoint32(words[0]);
|
|
load_status_ = BIN_SECTION;
|
|
break;
|
|
}
|
|
case BIN_SECTION: {
|
|
if (words.size() != num_resources_) {
|
|
ReportError(line);
|
|
return;
|
|
}
|
|
for (const std::string& dim_str : words) {
|
|
vbp_.add_resource_capacity(strtoint64(dim_str));
|
|
}
|
|
load_status_ = NUMBER_OF_ITEMS_SECTION;
|
|
break;
|
|
}
|
|
case NUMBER_OF_ITEMS_SECTION: {
|
|
if (words.size() != 1) {
|
|
ReportError(line);
|
|
return;
|
|
}
|
|
num_declared_items_ = strtoint32(words[0]);
|
|
load_status_ = ITEM_SECTION;
|
|
break;
|
|
}
|
|
case ITEM_SECTION: {
|
|
if (words.size() != num_resources_ + 1) {
|
|
ReportError(line);
|
|
return;
|
|
}
|
|
Item* const item = vbp_.add_item();
|
|
for (int i = 0; i < num_resources_; ++i) {
|
|
item->add_resource_usage(strtoint64(words[i]));
|
|
}
|
|
item->set_num_copies(strtoint32(words[num_resources_]));
|
|
item->set_max_number_of_copies_per_bin(item->num_copies());
|
|
break;
|
|
}
|
|
case ERROR_FOUND: {
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
int VbpParser::strtoint32(const std::string& word) {
|
|
int result;
|
|
CHECK(absl::SimpleAtoi(word, &result));
|
|
return result;
|
|
}
|
|
|
|
int64_t VbpParser::strtoint64(const std::string& word) {
|
|
int64_t result;
|
|
CHECK(absl::SimpleAtoi(word, &result));
|
|
return result;
|
|
}
|
|
|
|
} // namespace vbp
|
|
} // namespace packing
|
|
} // namespace operations_research
|