22 #include "absl/strings/string_view.h"
23 #include "absl/synchronization/mutex.h"
29 using ::operations_research::sat::LinearBooleanProblem;
30 using ::operations_research::sat::LinearObjective;
44 return "OPTIMAL_SOLUTION_FOUND";
46 return "SOLUTION_FOUND";
50 return "LIMIT_REACHED";
52 return "INFORMATION_FOUND";
60 LOG(DFATAL) <<
"Invalid Status " <<
static_cast<int>(
status);
61 return "UNKNOWN Status";
70 : original_problem_(problem),
72 update_stamp_(kInitialStampValue + 1),
73 is_fixed_(problem.num_variables(), false),
74 fixed_values_(problem.num_variables(), false),
76 solution_(problem,
"AllZero"),
77 assignment_preference_(),
78 lower_bound_(std::numeric_limits<int64_t>::
min()),
79 upper_bound_(std::numeric_limits<int64_t>::
max()) {
82 const LinearObjective& objective = problem.objective();
84 for (
int i = 0; i < objective.coefficients_size(); ++i) {
86 lower_bound_ += std::min<int64_t>(int64_t{0}, objective.coefficients(i));
97 const std::string kIndent(25,
' ');
99 bool new_lp_values =
false;
101 if (lp_values_ != learned_info.
lp_values) {
103 new_lp_values =
true;
104 VLOG(1) << kIndent +
"New LP values.";
108 bool new_binary_clauses =
false;
110 const int old_num = binary_clause_manager_.
NumClauses();
112 const int num_vars = original_problem_.num_variables();
114 binary_clause_manager_.
Add(c);
117 if (binary_clause_manager_.
NumClauses() > old_num) {
118 new_binary_clauses =
true;
119 VLOG(1) << kIndent +
"Num binary clauses: "
124 bool new_solution =
false;
130 VLOG(1) << kIndent +
"New solution.";
133 bool new_lower_bound =
false;
136 new_lower_bound =
true;
137 VLOG(1) << kIndent +
"New lower bound.";
144 parameters_.relative_gap_limit() *
155 int num_newly_fixed_variables = 0;
157 const VariableIndex
var(
literal.Variable().value());
158 if (
var >= original_problem_.num_variables()) {
162 if (is_fixed_[
var]) {
168 is_fixed_[
var] =
true;
170 ++num_newly_fixed_variables;
173 if (num_newly_fixed_variables > 0) {
174 int num_fixed_variables = 0;
175 for (
const bool is_fixed : is_fixed_) {
177 ++num_fixed_variables;
180 VLOG(1) << kIndent << num_newly_fixed_variables
181 <<
" newly fixed variables (" << num_fixed_variables <<
" / "
182 << is_fixed_.size() <<
").";
183 if (num_fixed_variables == is_fixed_.size()) {
186 for (VariableIndex
var(0);
var < is_fixed_.size(); ++
var) {
190 solution_ = fixed_solution;
194 VLOG(1) << kIndent <<
"Optimal";
201 bool known_status =
false;
210 const bool updated = new_lp_values || new_binary_clauses || new_solution ||
211 new_lower_bound || num_newly_fixed_variables > 0 ||
213 if (updated) ++update_stamp_;
220 if (is_fixed_[
var]) {
246 lower_bound_ = upper_bound_ - 1;
std::string StatString() const
static std::string GetStatusString(Status status)
BopOptimizerBase(absl::string_view name)
virtual ~BopOptimizerBase()
void SetValue(VariableIndex var, bool value)
int64_t lower_bound() const
bool MergeLearnedInfo(const LearnedInfo &learned_info, BopOptimizerBase::Status optimization_status)
const std::vector< sat::BinaryClause > & NewlyAddedBinaryClauses() const
LearnedInfo GetLearnedInfo() const
static const int64_t kInitialStampValue
ProblemState(const sat::LinearBooleanProblem &problem)
void SynchronizationDone()
int64_t upper_bound() const
const absl::StrongVector< VariableIndex, bool > & is_fixed() const
const std::vector< BinaryClause > & newly_added() const
BooleanVariable Variable() const
Collection of objects used to extend the Constraint Solver library.
#define IF_STATS_ENABLED(instructions)
#define SCOPED_TIME_STAT(stats)
std::vector< sat::Literal > fixed_literals
std::vector< sat::BinaryClause > binary_clauses
#define VLOG(verboselevel)