85 is_fixed_(problem.num_variables(), false),
86 fixed_values_(problem.num_variables(), false),
88 solution_(problem,
"AllZero"),
89 assignment_preference_(),
90 lower_bound_(
std::numeric_limits<int64_t>::min()),
91 upper_bound_(
std::numeric_limits<int64_t>::max()) {
98 lower_bound_ += std::min<int64_t>(int64_t{0}, objective.
coefficients(i));
100 upper_bound_ = solution_.IsFeasible() ? solution_.GetCost()
101 : std::numeric_limits<int64_t>::max();
109 const std::string kIndent(25,
' ');
111 bool new_lp_values =
false;
113 if (lp_values_ != learned_info.
lp_values) {
115 new_lp_values =
true;
116 VLOG(1) << kIndent +
"New LP values.";
120 bool new_binary_clauses =
false;
122 const int old_num = binary_clause_manager_.NumClauses();
124 const int num_vars = original_problem_.num_variables();
125 if (c.a.Variable() < num_vars && c.b.Variable() < num_vars) {
126 binary_clause_manager_.Add(c);
129 if (binary_clause_manager_.NumClauses() > old_num) {
130 new_binary_clauses =
true;
131 VLOG(1) << kIndent +
"Num binary clauses: "
132 << binary_clause_manager_.NumClauses();
136 bool new_solution =
false;
138 (!solution_.IsFeasible() ||
142 VLOG(1) << kIndent +
"New solution.";
145 bool new_lower_bound =
false;
148 new_lower_bound =
true;
149 VLOG(1) << kIndent +
"New lower bound.";
152 if (solution_.IsFeasible()) {
153 upper_bound_ = std::min(
upper_bound(), solution_.GetCost());
156 parameters_.relative_gap_limit() *
167 int num_newly_fixed_variables = 0;
169 const VariableIndex var(literal.
Variable().value());
170 if (var >= original_problem_.num_variables()) {
174 if (is_fixed_[var]) {
175 if (fixed_values_[var] != value) {
180 is_fixed_[var] =
true;
181 fixed_values_[var] = value;
182 ++num_newly_fixed_variables;
185 if (num_newly_fixed_variables > 0) {
186 int num_fixed_variables = 0;
187 for (
const bool is_fixed : is_fixed_) {
189 ++num_fixed_variables;
192 VLOG(1) << kIndent << num_newly_fixed_variables
193 <<
" newly fixed variables (" << num_fixed_variables <<
" / "
194 << is_fixed_.size() <<
").";
195 if (num_fixed_variables == is_fixed_.size()) {
198 for (VariableIndex var(0); var < is_fixed_.size(); ++var) {
199 fixed_solution.
SetValue(var, fixed_values_[var]);
202 solution_ = fixed_solution;
204 if (solution_.IsFeasible()) {
206 VLOG(1) << kIndent <<
"Optimal";
213 bool known_status =
false;
222 const bool updated = new_lp_values || new_binary_clauses || new_solution ||
223 new_lower_bound || num_newly_fixed_variables > 0 ||
225 if (updated) ++update_stamp_;
231 for (VariableIndex var(0); var < is_fixed_.size(); ++var) {
232 if (is_fixed_[var]) {
233 learned_info.fixed_literals.push_back(
234 sat::Literal(sat::BooleanVariable(var.value()), fixed_values_[var]));
237 learned_info.solution = solution_;
239 learned_info.lp_values = lp_values_;
253 CHECK(!solution_.IsFeasible());
254 if (
upper_bound() == std::numeric_limits<int64_t>::max()) {
255 lower_bound_ = std::numeric_limits<int64_t>::max();
256 upper_bound_ = std::numeric_limits<int64_t>::max() - 1;
258 lower_bound_ = upper_bound_ - 1;