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