OR-Tools  8.1
complete_optimizer.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 
15 
16 #include "ortools/bop/bop_util.h"
18 
19 namespace operations_research {
20 namespace bop {
21 
24  state_update_stamp_(ProblemState::kInitialStampValue),
25  initialized_(false),
26  assumptions_already_added_(false) {
27  // This is in term of number of variables not at their minimal value.
28  lower_bound_ = sat::Coefficient(0);
29  upper_bound_ = sat::kCoefficientMax;
30 }
31 
33 
34 BopOptimizerBase::Status SatCoreBasedOptimizer::SynchronizeIfNeeded(
35  const ProblemState& problem_state) {
36  if (state_update_stamp_ == problem_state.update_stamp()) {
38  }
39  state_update_stamp_ = problem_state.update_stamp();
40 
41  // Note that if the solver is not empty, this only load the newly learned
42  // information.
43  const BopOptimizerBase::Status status =
44  LoadStateProblemToSatSolver(problem_state, &solver_);
45  if (status != BopOptimizerBase::CONTINUE) return status;
46 
47  if (!initialized_) {
48  // Initialize the algorithm.
50  problem_state.original_problem().objective(), &offset_, &repository_);
51  initialized_ = true;
52 
53  // This is used by the "stratified" approach.
54  stratified_lower_bound_ = sat::Coefficient(0);
55  for (sat::EncodingNode* n : nodes_) {
56  stratified_lower_bound_ = std::max(stratified_lower_bound_, n->weight());
57  }
58  }
59 
60  // Extract the new upper bound.
61  if (problem_state.solution().IsFeasible()) {
62  upper_bound_ = problem_state.solution().GetCost() + offset_;
63  }
65 }
66 
67 sat::SatSolver::Status SatCoreBasedOptimizer::SolveWithAssumptions() {
68  const std::vector<sat::Literal> assumptions =
70  stratified_lower_bound_,
71  &lower_bound_, &nodes_, &solver_);
72  return solver_.ResetAndSolveWithGivenAssumptions(assumptions);
73 }
74 
75 // Only run this if there is an objective.
77  const ProblemState& problem_state) const {
78  return problem_state.original_problem().objective().literals_size() > 0;
79 }
80 
82  const BopParameters& parameters, const ProblemState& problem_state,
83  LearnedInfo* learned_info, TimeLimit* time_limit) {
85  CHECK(learned_info != nullptr);
86  CHECK(time_limit != nullptr);
87  learned_info->Clear();
88 
89  const BopOptimizerBase::Status sync_status =
90  SynchronizeIfNeeded(problem_state);
91  if (sync_status != BopOptimizerBase::CONTINUE) {
92  return sync_status;
93  }
94 
95  int64 conflict_limit = parameters.max_number_of_conflicts_in_random_lns();
96  double deterministic_time_at_last_sync = solver_.deterministic_time();
97  while (!time_limit->LimitReached()) {
98  sat::SatParameters sat_params = solver_.parameters();
99  sat_params.set_max_time_in_seconds(time_limit->GetTimeLeft());
100  sat_params.set_max_deterministic_time(
101  time_limit->GetDeterministicTimeLeft());
102  sat_params.set_random_seed(parameters.random_seed());
103  sat_params.set_max_number_of_conflicts(conflict_limit);
104  solver_.SetParameters(sat_params);
105 
106  const int64 old_num_conflicts = solver_.num_failures();
107  const sat::SatSolver::Status sat_status =
108  assumptions_already_added_ ? solver_.Solve() : SolveWithAssumptions();
109  time_limit->AdvanceDeterministicTime(solver_.deterministic_time() -
110  deterministic_time_at_last_sync);
111  deterministic_time_at_last_sync = solver_.deterministic_time();
112 
113  assumptions_already_added_ = true;
114  conflict_limit -= solver_.num_failures() - old_num_conflicts;
115  learned_info->lower_bound = lower_bound_.value() - offset_.value();
116 
117  // This is possible because we over-constrain the objective.
118  if (sat_status == sat::SatSolver::INFEASIBLE) {
119  return problem_state.solution().IsFeasible()
122  }
123 
124  ExtractLearnedInfoFromSatSolver(&solver_, learned_info);
125  if (sat_status == sat::SatSolver::LIMIT_REACHED || conflict_limit < 0) {
127  }
128  if (sat_status == sat::SatSolver::FEASIBLE) {
129  stratified_lower_bound_ =
130  MaxNodeWeightSmallerThan(nodes_, stratified_lower_bound_);
131 
132  // We found a better solution!
133  SatAssignmentToBopSolution(solver_.Assignment(), &learned_info->solution);
134  if (stratified_lower_bound_ > 0) {
135  assumptions_already_added_ = false;
137  }
139  }
140 
141  // The interesting case: we have a core.
142  // TODO(user): Check that this cannot fail because of the conflict limit.
143  std::vector<sat::Literal> core = solver_.GetLastIncompatibleDecisions();
144  sat::MinimizeCore(&solver_, &core);
145 
146  const sat::Coefficient min_weight = sat::ComputeCoreMinWeight(nodes_, core);
147  sat::ProcessCore(core, min_weight, &repository_, &nodes_, &solver_);
148  assumptions_already_added_ = false;
149  }
151 }
152 
153 } // namespace bop
154 } // namespace operations_research
operations_research::sat::SatSolver::Status
Status
Definition: sat_solver.h:181
operations_research::bop::BopOptimizerBase::SOLUTION_FOUND
@ SOLUTION_FOUND
Definition: bop_base.h:63
max
int64 max
Definition: alldiff_cst.cc:139
complete_optimizer.h
operations_research::bop::ProblemState::solution
const BopSolution & solution() const
Definition: bop_base.h:193
operations_research::sat::SatSolver::Assignment
const VariablesAssignment & Assignment() const
Definition: sat_solver.h:363
operations_research::bop::LearnedInfo::Clear
void Clear()
Definition: bop_base.h:255
operations_research::sat::ProcessCore
void ProcessCore(const std::vector< Literal > &core, Coefficient min_weight, std::deque< EncodingNode > *repository, std::vector< EncodingNode * > *nodes, SatSolver *solver)
Definition: encoding.cc:445
operations_research::bop::SatCoreBasedOptimizer::Optimize
Status Optimize(const BopParameters &parameters, const ProblemState &problem_state, LearnedInfo *learned_info, TimeLimit *time_limit) override
Definition: complete_optimizer.cc:81
operations_research::bop::LearnedInfo::solution
BopSolution solution
Definition: bop_base.h:266
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
operations_research::sat::SatSolver::GetLastIncompatibleDecisions
std::vector< Literal > GetLastIncompatibleDecisions()
Definition: sat_solver.cc:1272
operations_research::sat::SatSolver::FEASIBLE
@ FEASIBLE
Definition: sat_solver.h:184
operations_research::bop::LoadStateProblemToSatSolver
BopOptimizerBase::Status LoadStateProblemToSatSolver(const ProblemState &problem_state, sat::SatSolver *sat_solver)
Definition: bop_util.cc:87
operations_research::bop::BopOptimizerBase
Definition: bop_base.h:40
int64
int64_t int64
Definition: integral_types.h:34
operations_research::TimeLimit
A simple class to enforce both an elapsed time limit and a deterministic time limit in the same threa...
Definition: time_limit.h:105
operations_research::sat::SatSolver::INFEASIBLE
@ INFEASIBLE
Definition: sat_solver.h:183
operations_research::sat::MinimizeCore
void MinimizeCore(SatSolver *solver, std::vector< Literal > *core)
Definition: sat_solver.cc:2547
SCOPED_TIME_STAT
#define SCOPED_TIME_STAT(stats)
Definition: stats.h:436
operations_research::bop::BopOptimizerBase::stats_
StatsGroup stats_
Definition: bop_base.h:100
operations_research::bop::SatAssignmentToBopSolution
void SatAssignmentToBopSolution(const sat::VariablesAssignment &assignment, BopSolution *solution)
Definition: bop_util.cc:121
operations_research::sat::ComputeCoreMinWeight
Coefficient ComputeCoreMinWeight(const std::vector< EncodingNode * > &nodes, const std::vector< Literal > &core)
Definition: encoding.cc:418
operations_research::bop::BopOptimizerBase::INFEASIBLE
@ INFEASIBLE
Definition: bop_base.h:64
time_limit
SharedTimeLimit * time_limit
Definition: cp_model_solver.cc:2103
operations_research::bop::SatCoreBasedOptimizer::ShouldBeRun
bool ShouldBeRun(const ProblemState &problem_state) const override
Definition: complete_optimizer.cc:76
operations_research::sat::kCoefficientMax
const Coefficient kCoefficientMax(std::numeric_limits< Coefficient::ValueType >::max())
operations_research::bop::LearnedInfo
Definition: bop_base.h:245
operations_research::sat::SatSolver::ResetAndSolveWithGivenAssumptions
Status ResetAndSolveWithGivenAssumptions(const std::vector< Literal > &assumptions)
Definition: sat_solver.cc:947
operations_research::bop::ProblemState
Definition: bop_base.h:111
operations_research::bop::SatCoreBasedOptimizer::SatCoreBasedOptimizer
SatCoreBasedOptimizer(const std::string &name)
Definition: complete_optimizer.cc:22
operations_research::sat::SatSolver::deterministic_time
double deterministic_time() const
Definition: sat_solver.cc:92
operations_research::bop::ExtractLearnedInfoFromSatSolver
void ExtractLearnedInfoFromSatSolver(sat::SatSolver *solver, LearnedInfo *info)
Definition: bop_util.cc:98
operations_research::bop::ProblemState::original_problem
const sat::LinearBooleanProblem & original_problem() const
Definition: bop_base.h:198
bop_util.h
operations_research::sat::ReduceNodesAndExtractAssumptions
std::vector< Literal > ReduceNodesAndExtractAssumptions(Coefficient upper_bound, Coefficient stratified_lower_bound, Coefficient *lower_bound, std::vector< EncodingNode * > *nodes, SatSolver *solver)
Definition: encoding.cc:366
operations_research::bop::BopOptimizerBase::OPTIMAL_SOLUTION_FOUND
@ OPTIMAL_SOLUTION_FOUND
Definition: bop_base.h:62
operations_research::sat::MaxNodeWeightSmallerThan
Coefficient MaxNodeWeightSmallerThan(const std::vector< EncodingNode * > &nodes, Coefficient upper_bound)
Definition: encoding.cc:433
operations_research::sat::SatSolver::num_failures
int64 num_failures() const
Definition: sat_solver.cc:84
operations_research::bop::LearnedInfo::lower_bound
int64 lower_bound
Definition: bop_base.h:269
operations_research::bop::BopSolution::IsFeasible
bool IsFeasible() const
Definition: bop_solution.h:69
operations_research::sat::SatSolver::Solve
Status Solve()
Definition: sat_solver.cc:972
operations_research::sat::EncodingNode
Definition: encoding.h:53
boolean_problem.h
operations_research::bop::BopOptimizerBase::CONTINUE
@ CONTINUE
Definition: bop_base.h:76
operations_research::bop::BopSolution::GetCost
int64 GetCost() const
Definition: bop_solution.h:50
operations_research::sat::SatSolver::parameters
const SatParameters & parameters() const
Definition: sat_solver.cc:110
operations_research::bop::SatCoreBasedOptimizer::~SatCoreBasedOptimizer
~SatCoreBasedOptimizer() override
Definition: complete_optimizer.cc:32
operations_research::bop::BopOptimizerBase::Status
Status
Definition: bop_base.h:61
operations_research::sat::SatSolver::LIMIT_REACHED
@ LIMIT_REACHED
Definition: sat_solver.h:185
CHECK
#define CHECK(condition)
Definition: base/logging.h:495
parameters
SatParameters parameters
Definition: cp_model_fz_solver.cc:108
name
const std::string name
Definition: default_search.cc:808
operations_research::sat::CreateInitialEncodingNodes
std::vector< EncodingNode * > CreateInitialEncodingNodes(const std::vector< Literal > &literals, const std::vector< Coefficient > &coeffs, Coefficient *offset, std::deque< EncodingNode > *repository)
Definition: encoding.cc:302
operations_research::bop::ProblemState::update_stamp
int64 update_stamp() const
Definition: bop_base.h:153
operations_research::sat::SatSolver::SetParameters
void SetParameters(const SatParameters &parameters)
Definition: sat_solver.cc:115