OR-Tools  9.6
opb_reader.h
Go to the documentation of this file.
1 // Copyright 2010-2022 Google LLC
2 // Licensed under the Apache License, Version 2.0 (the "License");
3 // you may not use this file except in compliance with the License.
4 // You may obtain a copy of the License at
5 //
6 // http://www.apache.org/licenses/LICENSE-2.0
7 //
8 // Unless required by applicable law or agreed to in writing, software
9 // distributed under the License is distributed on an "AS IS" BASIS,
10 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11 // See the License for the specific language governing permissions and
12 // limitations under the License.
13 
14 #ifndef OR_TOOLS_SAT_OPB_READER_H_
15 #define OR_TOOLS_SAT_OPB_READER_H_
16 
17 #include <algorithm>
18 #include <cstdint>
19 #include <memory>
20 #include <string>
21 #include <vector>
22 
23 #include "absl/strings/numbers.h"
24 #include "absl/strings/str_split.h"
25 #include "ortools/base/logging.h"
26 #include "ortools/base/macros.h"
27 #include "ortools/sat/boolean_problem.pb.h"
29 
30 namespace operations_research {
31 namespace sat {
32 
33 // This class loads a file in pbo file format into a LinearBooleanProblem.
34 // The format is described here:
35 // http://www.cril.univ-artois.fr/PB12/format.pdf
36 class OpbReader {
37  public:
38  OpbReader() {}
39 
40  // Loads the given opb filename into the given problem.
41  bool Load(const std::string& filename, LinearBooleanProblem* problem) {
42  problem->Clear();
43  problem->set_name(ExtractProblemName(filename));
44 
45  num_variables_ = 0;
46  int num_lines = 0;
47  for (const std::string& line : FileLines(filename)) {
48  ++num_lines;
49  ProcessNewLine(problem, line);
50  }
51  if (num_lines == 0) {
52  LOG(FATAL) << "File '" << filename << "' is empty or can't be read.";
53  }
54  problem->set_num_variables(num_variables_);
55  return true;
56  }
57 
58  private:
59  // Since the problem name is not stored in the cnf format, we infer it from
60  // the file name.
61  static std::string ExtractProblemName(const std::string& filename) {
62  const int found = filename.find_last_of('/');
63  const std::string problem_name =
64  found != std::string::npos ? filename.substr(found + 1) : filename;
65  return problem_name;
66  }
67 
68  void ProcessNewLine(LinearBooleanProblem* problem, const std::string& line) {
69  const std::vector<std::string> words =
70  absl::StrSplit(line, absl::ByAnyChar(" ;"), absl::SkipEmpty());
71  if (words.empty() || words[0].empty() || words[0][0] == '*') {
72  return;
73  }
74 
75  if (words[0] == "min:") {
76  LinearObjective* objective = problem->mutable_objective();
77  for (int i = 1; i < words.size(); ++i) {
78  const std::string& word = words[i];
79  if (word.empty() || word[0] == ';') continue;
80  if (word[0] == 'x') {
81  int literal;
82  CHECK(absl::SimpleAtoi(word.substr(1), &literal));
83  num_variables_ = std::max(num_variables_, literal);
84  objective->add_literals(literal);
85  } else {
86  int64_t value;
87  CHECK(absl::SimpleAtoi(word, &value));
88  objective->add_coefficients(value);
89  }
90  }
91  if (objective->literals_size() != objective->coefficients_size()) {
92  LOG(INFO) << "words.size() = " << words.size();
93  LOG(FATAL) << "Failed to parse objective:\n " << line;
94  }
95  return;
96  }
97  LinearBooleanConstraint* constraint = problem->add_constraints();
98  for (int i = 0; i < words.size(); ++i) {
99  const std::string& word = words[i];
100  CHECK(!word.empty());
101  if (word == ">=") {
102  CHECK_LT(i + 1, words.size());
103  int64_t value;
104  CHECK(absl::SimpleAtoi(words[i + 1], &value));
105  constraint->set_lower_bound(value);
106  break;
107  } else if (word == "=") {
108  CHECK_LT(i + 1, words.size());
109  int64_t value;
110  CHECK(absl::SimpleAtoi(words[i + 1], &value));
111  constraint->set_upper_bound(value);
112  constraint->set_lower_bound(value);
113  break;
114  } else {
115  if (word[0] == 'x') {
116  int literal;
117  CHECK(absl::SimpleAtoi(word.substr(1), &literal));
118  num_variables_ = std::max(num_variables_, literal);
119  constraint->add_literals(literal);
120  } else {
121  int64_t value;
122  CHECK(absl::SimpleAtoi(words[i], &value));
123  constraint->add_coefficients(value);
124  }
125  }
126  }
127  if (constraint->literals_size() != constraint->coefficients_size()) {
128  LOG(FATAL) << "Failed to parse constraint:\n " << line;
129  }
130  }
131 
132  int num_variables_;
133  DISALLOW_COPY_AND_ASSIGN(OpbReader);
134 };
135 
136 } // namespace sat
137 } // namespace operations_research
138 
139 #endif // OR_TOOLS_SAT_OPB_READER_H_
int64_t max
Definition: alldiff_cst.cc:140
bool Load(const std::string &filename, LinearBooleanProblem *problem)
Definition: opb_reader.h:41
int64_t value
Collection of objects used to extend the Constraint Solver library.
Literal literal
Definition: optimization.cc:88
int line
Definition: parse_proto.cc:31