Files
ortools-clone/examples/cpp/opb_reader.h

139 lines
4.5 KiB
C
Raw Normal View History

2018-11-10 18:00:53 +01:00
// Copyright 2010-2018 Google LLC
2013-12-12 14:43:04 +00:00
// 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.
2013-12-12 14:43:04 +00:00
#ifndef OR_TOOLS_SAT_OPB_READER_H_
#define OR_TOOLS_SAT_OPB_READER_H_
#include <algorithm>
#include <memory>
2013-12-12 14:43:04 +00:00
#include <string>
#include <vector>
#include "absl/strings/numbers.h"
dotnet: Remove reference to dotnet release command - Currently not implemented... Add abseil patch - Add patches/absl-config.cmake Makefile: Add abseil-cpp on unix - Force abseil-cpp SHA1 to 45221cc note: Just before the PR #136 which break all CMake Makefile: Add abseil-cpp on windows - Force abseil-cpp SHA1 to 45221cc note: Just before the PR #136 which break all CMake CMake: Add abseil-cpp - Force abseil-cpp SHA1 to 45221cc note: Just before the PR #136 which break all CMake port to absl: C++ Part - Fix warning with the use of ABSL_MUST_USE_RESULT > The macro must appear as the very first part of a function declaration or definition: ... Note: past advice was to place the macro after the argument list. src: dependencies/sources/abseil-cpp-master/absl/base/attributes.h:418 - Rename enum after windows clash - Remove non compact table constraints - Change index type from int64 to int in routing library - Fix file_nonport compilation on windows - Fix another naming conflict with windows (NO_ERROR is a macro) - Cleanup hash containers; work on sat internals - Add optional_boolean sub-proto Sync cpp examples with internal code - reenable issue173 after reducing number of loops port to absl: Python Part - Add back cp_model.INT32_MIN|MAX for examples Update Python examples - Add random_tsp.py - Run words_square example - Run magic_square in python tests port to absl: Java Part - Fix compilation of the new routing parameters in java - Protect some code from SWIG parsing Update Java Examples port to absl: .Net Part Update .Net examples work on sat internals; Add C++ CP-SAT CpModelBuilder API; update sample code and recipes to use the new API; sync with internal code Remove VS 2015 in Appveyor-CI - abseil-cpp does not support VS 2015... improve tables upgrade C++ sat examples to use the new API; work on sat internals update license dates rewrite jobshop_ft06_distance.py to use the CP-SAT solver rename last example revert last commit more work on SAT internals fix
2018-10-31 16:18:18 +01:00
#include "absl/strings/str_split.h"
2018-06-08 16:40:43 +02:00
#include "ortools/base/filelineiter.h"
#include "ortools/base/logging.h"
#include "ortools/base/macros.h"
#include "ortools/sat/boolean_problem.pb.h"
2013-12-12 14:43:04 +00:00
namespace operations_research {
namespace sat {
// This class loads a file in pbo file format into a LinearBooleanProblem.
// The format is described here:
// http://www.cril.univ-artois.fr/PB12/format.pdf
class OpbReader {
public:
OpbReader() {}
// Loads the given opb filename into the given problem.
bool Load(const std::string& filename, LinearBooleanProblem* problem) {
2013-12-12 14:43:04 +00:00
problem->Clear();
problem->set_name(ExtractProblemName(filename));
num_variables_ = 0;
int num_lines = 0;
for (const std::string& line : FileLines(filename)) {
2013-12-12 14:43:04 +00:00
++num_lines;
ProcessNewLine(problem, line);
}
if (num_lines == 0) {
LOG(FATAL) << "File '" << filename << "' is empty or can't be read.";
}
problem->set_num_variables(num_variables_);
return true;
}
private:
// Since the problem name is not stored in the cnf format, we infer it from
// the file name.
static std::string ExtractProblemName(const std::string& filename) {
2013-12-12 14:43:04 +00:00
const int found = filename.find_last_of("/");
2014-01-08 12:01:58 +00:00
const std::string problem_name =
found != std::string::npos ? filename.substr(found + 1) : filename;
2013-12-12 14:43:04 +00:00
return problem_name;
}
void ProcessNewLine(LinearBooleanProblem* problem, const std::string& line) {
2014-05-21 12:56:57 +00:00
const std::vector<std::string> words =
absl::StrSplit(line, absl::ByAnyChar(" ;"), absl::SkipEmpty());
if (words.empty() || words[0].empty() || words[0][0] == '*') {
2013-12-12 14:43:04 +00:00
return;
}
if (words[0] == "min:") {
LinearObjective* objective = problem->mutable_objective();
for (int i = 1; i < words.size(); ++i) {
const std::string& word = words[i];
2013-12-12 14:43:04 +00:00
if (word.empty() || word[0] == ';') continue;
if (word[0] == 'x') {
int literal;
CHECK(absl::SimpleAtoi(word.substr(1), &literal));
2013-12-12 14:43:04 +00:00
num_variables_ = std::max(num_variables_, literal);
objective->add_literals(literal);
} else {
int64 value;
CHECK(absl::SimpleAtoi(word, &value));
objective->add_coefficients(value);
2013-12-12 14:43:04 +00:00
}
}
if (objective->literals_size() != objective->coefficients_size()) {
LOG(INFO) << "words.size() = " << words.size();
LOG(FATAL) << "Failed to parse objective:\n " << line;
}
return;
}
LinearBooleanConstraint* constraint = problem->add_constraints();
for (int i = 0; i < words.size(); ++i) {
const std::string& word = words[i];
2013-12-12 14:43:04 +00:00
CHECK(!word.empty());
if (word == ">=") {
CHECK_LT(i + 1, words.size());
int64 value;
CHECK(absl::SimpleAtoi(words[i + 1], &value));
constraint->set_lower_bound(value);
2013-12-12 14:43:04 +00:00
break;
} else if (word == "=") {
CHECK_LT(i + 1, words.size());
int64 value;
CHECK(absl::SimpleAtoi(words[i + 1], &value));
constraint->set_upper_bound(value);
constraint->set_lower_bound(value);
2013-12-12 14:43:04 +00:00
break;
} else {
if (word[0] == 'x') {
int literal;
CHECK(absl::SimpleAtoi(word.substr(1), &literal));
2013-12-12 14:43:04 +00:00
num_variables_ = std::max(num_variables_, literal);
constraint->add_literals(literal);
} else {
int64 value;
CHECK(absl::SimpleAtoi(words[i], &value));
constraint->add_coefficients(value);
2013-12-12 14:43:04 +00:00
}
}
}
if (constraint->literals_size() != constraint->coefficients_size()) {
LOG(FATAL) << "Failed to parse constraint:\n " << line;
}
}
int num_variables_;
DISALLOW_COPY_AND_ASSIGN(OpbReader);
};
} // namespace sat
} // namespace operations_research
#endif // OR_TOOLS_SAT_OPB_READER_H_