OR-Tools  8.1
bop_util.cc
Go to the documentation of this file.
1 // Copyright 2010-2018 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 #include "ortools/bop/bop_util.h"
15 
16 #include <vector>
17 
20 #include "ortools/bop/bop_base.h"
23 #include "ortools/sat/sat_solver.h"
24 
25 namespace operations_research {
26 namespace bop {
27 namespace {
28 static const int kMaxLubyIndex = 30;
29 static const int kMaxBoost = 30;
30 
31 // Loads the problem state into the SAT solver. If the problem has already been
32 // loaded in the sat_solver, fixed variables and objective bounds are updated.
33 // Returns false when the problem is proved UNSAT.
34 bool InternalLoadStateProblemToSatSolver(const ProblemState& problem_state,
35  sat::SatSolver* sat_solver) {
36  const bool first_time = (sat_solver->NumVariables() == 0);
37  if (first_time) {
38  sat_solver->SetNumVariables(
39  problem_state.original_problem().num_variables());
40  } else {
41  // Backtrack the solver to be able to add new constraints.
42  sat_solver->Backtrack(0);
43  }
44 
45  // Set the fixed variables first so that loading the problem will be faster.
46  for (VariableIndex var(0); var < problem_state.is_fixed().size(); ++var) {
47  if (problem_state.is_fixed()[var]) {
48  if (!sat_solver->AddUnitClause(
49  sat::Literal(sat::BooleanVariable(var.value()),
50  problem_state.fixed_values()[var]))) {
51  return false;
52  }
53  }
54  }
55 
56  // Load the problem if not done yet.
57  if (first_time &&
58  !LoadBooleanProblem(problem_state.original_problem(), sat_solver)) {
59  return false;
60  }
61 
62  // Constrain the objective cost to be greater or equal to the lower bound,
63  // and to be smaller than the upper bound. If enforcing the strictier upper
64  // bound constraint leads to an UNSAT problem, it means the current solution
65  // is proved optimal (if the solution is feasible, else the problem is proved
66  // infeasible).
67  if (!AddObjectiveConstraint(problem_state.original_problem(),
68  problem_state.lower_bound() != kint64min,
69  sat::Coefficient(problem_state.lower_bound()),
70  problem_state.upper_bound() != kint64max,
71  sat::Coefficient(problem_state.upper_bound() - 1),
72  sat_solver)) {
73  return false;
74  }
75 
76  // Adds the new binary clauses.
77  sat_solver->TrackBinaryClauses(true);
78  if (!sat_solver->AddBinaryClauses(problem_state.NewlyAddedBinaryClauses())) {
79  return false;
80  }
81  sat_solver->ClearNewlyAddedBinaryClauses();
82 
83  return true;
84 }
85 } // anonymous namespace
86 
88  const ProblemState& problem_state, sat::SatSolver* sat_solver) {
89  if (InternalLoadStateProblemToSatSolver(problem_state, sat_solver)) {
91  }
92 
93  return problem_state.solution().IsFeasible()
96 }
97 
99  LearnedInfo* info) {
100  CHECK(nullptr != solver);
101  CHECK(nullptr != info);
102 
103  // This should never be called if the problem is UNSAT.
104  CHECK(!solver->IsModelUnsat());
105 
106  // Fixed variables.
107  info->fixed_literals.clear();
108  const sat::Trail& propagation_trail = solver->LiteralTrail();
109  const int root_size = solver->CurrentDecisionLevel() == 0
110  ? propagation_trail.Index()
111  : solver->Decisions().front().trail_index;
112  for (int trail_index = 0; trail_index < root_size; ++trail_index) {
113  info->fixed_literals.push_back(propagation_trail[trail_index]);
114  }
115 
116  // Binary clauses.
117  info->binary_clauses = solver->NewlyAddedBinaryClauses();
119 }
120 
122  BopSolution* solution) {
123  CHECK(solution != nullptr);
124 
125  // Only extract the variables of the initial problem.
126  CHECK_LE(solution->Size(), assignment.NumberOfVariables());
127  for (sat::BooleanVariable var(0); var < solution->Size(); ++var) {
128  CHECK(assignment.VariableIsAssigned(var));
129  const bool value = assignment.LiteralIsTrue(sat::Literal(var, true));
130  const VariableIndex bop_var_id(var.value());
131  solution->SetValue(bop_var_id, value);
132  }
133 }
134 
135 //------------------------------------------------------------------------------
136 // AdaptiveParameterValue
137 //------------------------------------------------------------------------------
139  : value_(initial_value), num_changes_(0) {}
140 
141 void AdaptiveParameterValue::Reset() { num_changes_ = 0; }
142 
144  ++num_changes_;
145  const double factor = 1.0 + 1.0 / (num_changes_ / 2.0 + 1);
146  value_ = std::min(1.0 - (1.0 - value_) / factor, value_ * factor);
147 }
148 
150  ++num_changes_;
151  const double factor = 1.0 + 1.0 / (num_changes_ / 2.0 + 1);
152  value_ = std::max(value_ / factor, 1.0 - (1.0 - value_) * factor);
153 }
154 
155 //------------------------------------------------------------------------------
156 // LubyAdaptiveParameterValue
157 //------------------------------------------------------------------------------
159  : luby_id_(0),
160  luby_boost_(0),
161  luby_value_(0),
162  difficulties_(kMaxLubyIndex, AdaptiveParameterValue(initial_value)) {
163  Reset();
164 }
165 
167  luby_id_ = 0;
168  luby_boost_ = 0;
169  luby_value_ = 0;
170  for (int i = 0; i < difficulties_.size(); ++i) {
171  difficulties_[i].Reset();
172  }
173 }
174 
176  const int luby_msb = MostSignificantBitPosition64(luby_value_);
177  difficulties_[luby_msb].Increase();
178 }
179 
181  const int luby_msb = MostSignificantBitPosition64(luby_value_);
182  difficulties_[luby_msb].Decrease();
183 }
184 
186  const int luby_msb = MostSignificantBitPosition64(luby_value_);
187  return difficulties_[luby_msb].value();
188 }
189 
191  ++luby_boost_;
192  return luby_boost_ >= kMaxBoost;
193 }
194 
196  ++luby_id_;
197  luby_value_ = sat::SUniv(luby_id_) << luby_boost_;
198 }
199 } // namespace bop
200 } // namespace operations_research
var
IntVar * var
Definition: expr_array.cc:1858
min
int64 min
Definition: alldiff_cst.cc:138
integral_types.h
operations_research::bop::LubyAdaptiveParameterValue::LubyAdaptiveParameterValue
LubyAdaptiveParameterValue(double initial_value)
Definition: bop_util.cc:158
operations_research::bop::BopSolution::Size
size_t Size() const
Definition: bop_solution.h:42
operations_research::bop::AdaptiveParameterValue::Decrease
void Decrease()
Definition: bop_util.cc:149
max
int64 max
Definition: alldiff_cst.cc:139
operations_research::bop::ProblemState::solution
const BopSolution & solution() const
Definition: bop_base.h:193
operations_research::bop::LubyAdaptiveParameterValue::BoostLuby
bool BoostLuby()
Definition: bop_util.cc:190
operations_research::sat::SatSolver
Definition: sat_solver.h:58
operations_research::bop::LubyAdaptiveParameterValue::UpdateLuby
void UpdateLuby()
Definition: bop_util.cc:195
value
int64 value
Definition: demon_profiler.cc:43
operations_research::sat::SatSolver::Decisions
const std::vector< Decision > & Decisions() const
Definition: sat_solver.h:360
operations_research
The vehicle routing library lets one model and solve generic vehicle routing problems ranging from th...
Definition: dense_doubly_linked_list.h:21
bop_solution.h
operations_research::bop::LoadStateProblemToSatSolver
BopOptimizerBase::Status LoadStateProblemToSatSolver(const ProblemState &problem_state, sat::SatSolver *sat_solver)
Definition: bop_util.cc:87
operations_research::sat::VariablesAssignment::LiteralIsTrue
bool LiteralIsTrue(Literal literal) const
Definition: sat_base.h:150
kint64min
static const int64 kint64min
Definition: integral_types.h:60
operations_research::bop::LubyAdaptiveParameterValue::Reset
void Reset()
Definition: bop_util.cc:166
operations_research::bop::AdaptiveParameterValue::Increase
void Increase()
Definition: bop_util.cc:143
sat_solver.h
operations_research::bop::BopSolution
Definition: bop_solution.h:31
operations_research::sat::Trail::Index
int Index() const
Definition: sat_base.h:378
operations_research::sat::SatSolver::CurrentDecisionLevel
int CurrentDecisionLevel() const
Definition: sat_solver.h:361
operations_research::sat::SUniv
int SUniv(int i)
Definition: restart.h:85
operations_research::bop::LearnedInfo::fixed_literals
std::vector< sat::Literal > fixed_literals
Definition: bop_base.h:263
operations_research::bop::SatAssignmentToBopSolution
void SatAssignmentToBopSolution(const sat::VariablesAssignment &assignment, BopSolution *solution)
Definition: bop_util.cc:121
operations_research::sat::SatSolver::LiteralTrail
const Trail & LiteralTrail() const
Definition: sat_solver.h:362
operations_research::bop::BopOptimizerBase::INFEASIBLE
@ INFEASIBLE
Definition: bop_base.h:64
operations_research::bop::LearnedInfo
Definition: bop_base.h:245
operations_research::sat::VariablesAssignment::NumberOfVariables
int NumberOfVariables() const
Definition: sat_base.h:170
operations_research::bop::ProblemState
Definition: bop_base.h:111
operations_research::bop::LubyAdaptiveParameterValue::IncreaseParameter
void IncreaseParameter()
Definition: bop_util.cc:175
operations_research::bop::LearnedInfo::binary_clauses
std::vector< sat::BinaryClause > binary_clauses
Definition: bop_base.h:278
operations_research::bop::ExtractLearnedInfoFromSatSolver
void ExtractLearnedInfoFromSatSolver(sat::SatSolver *solver, LearnedInfo *info)
Definition: bop_util.cc:98
basictypes.h
bop_util.h
operations_research::MostSignificantBitPosition64
int MostSignificantBitPosition64(uint64 n)
Definition: bitset.h:231
operations_research::sat::LoadBooleanProblem
bool LoadBooleanProblem(const LinearBooleanProblem &problem, SatSolver *solver)
Definition: boolean_problem.cc:219
CHECK_LE
#define CHECK_LE(val1, val2)
Definition: base/logging.h:699
operations_research::bop::BopOptimizerBase::OPTIMAL_SOLUTION_FOUND
@ OPTIMAL_SOLUTION_FOUND
Definition: bop_base.h:62
operations_research::bop::LubyAdaptiveParameterValue::GetParameterValue
double GetParameterValue() const
Definition: bop_util.cc:185
operations_research::bop::AdaptiveParameterValue
Definition: bop_util.h:49
operations_research::sat::Literal
Definition: sat_base.h:64
operations_research::bop::BopSolution::IsFeasible
bool IsFeasible() const
Definition: bop_solution.h:69
operations_research::bop::AdaptiveParameterValue::AdaptiveParameterValue
AdaptiveParameterValue(double initial_value)
Definition: bop_util.cc:138
operations_research::sat::SatSolver::NewlyAddedBinaryClauses
const std::vector< BinaryClause > & NewlyAddedBinaryClauses()
Definition: sat_solver.cc:932
boolean_problem.h
operations_research::sat::VariablesAssignment::VariableIsAssigned
bool VariableIsAssigned(BooleanVariable var) const
Definition: sat_base.h:158
operations_research::sat::SatSolver::ClearNewlyAddedBinaryClauses
void ClearNewlyAddedBinaryClauses()
Definition: sat_solver.cc:936
bop_base.h
operations_research::bop::BopOptimizerBase::CONTINUE
@ CONTINUE
Definition: bop_base.h:76
operations_research::sat::AddObjectiveConstraint
bool AddObjectiveConstraint(const LinearBooleanProblem &problem, bool use_lower_bound, Coefficient lower_bound, bool use_upper_bound, Coefficient upper_bound, SatSolver *solver)
Definition: boolean_problem.cc:336
operations_research::bop::LubyAdaptiveParameterValue::DecreaseParameter
void DecreaseParameter()
Definition: bop_util.cc:180
operations_research::sat::VariablesAssignment
Definition: sat_base.h:122
operations_research::bop::BopOptimizerBase::Status
Status
Definition: bop_base.h:61
CHECK
#define CHECK(condition)
Definition: base/logging.h:495
operations_research::sat::SatSolver::IsModelUnsat
bool IsModelUnsat() const
Definition: sat_solver.h:137
operations_research::bop::BopSolution::SetValue
void SetValue(VariableIndex var, bool value)
Definition: bop_solution.h:36
operations_research::sat::Trail
Definition: sat_base.h:233
kint64max
static const int64 kint64max
Definition: integral_types.h:62
operations_research::bop::AdaptiveParameterValue::Reset
void Reset()
Definition: bop_util.cc:141