OR-Tools  8.0
bop_solver.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_solver.h"
15 
16 #include <string>
17 #include <vector>
18 
19 #include "google/protobuf/text_format.h"
21 #include "ortools/base/stl_util.h"
22 #include "ortools/bop/bop_fs.h"
23 #include "ortools/bop/bop_lns.h"
24 #include "ortools/bop/bop_ls.h"
26 #include "ortools/bop/bop_util.h"
28 #include "ortools/glop/lp_solver.h"
31 #include "ortools/sat/lp_utils.h"
32 #include "ortools/sat/sat_solver.h"
33 #include "ortools/util/bitset.h"
34 
35 namespace operations_research {
36 namespace bop {
37 namespace {
38 
39 using ::operations_research::sat::LinearBooleanProblem;
40 using ::operations_research::glop::ColIndex;
42 
43 // Updates the problem_state when the solution is proved optimal or the problem
44 // is proved infeasible.
45 // Returns true when the problem_state has been changed.
46 bool UpdateProblemStateBasedOnStatus(BopOptimizerBase::Status status,
47  ProblemState* problem_state) {
48  CHECK(nullptr != problem_state);
49 
51  problem_state->MarkAsOptimal();
52  return true;
53  }
54 
55  if (BopOptimizerBase::INFEASIBLE == status) {
56  problem_state->MarkAsInfeasible();
57  return true;
58  }
59 
60  return false;
61 }
62 
63 } // anonymous namespace
64 
65 //------------------------------------------------------------------------------
66 // BopSolver
67 //------------------------------------------------------------------------------
68 BopSolver::BopSolver(const LinearBooleanProblem& problem)
69  : problem_(problem),
70  problem_state_(problem),
71  parameters_(),
72  stats_("BopSolver") {
73  SCOPED_TIME_STAT(&stats_);
74 }
75 
77 
79  std::unique_ptr<TimeLimit> time_limit =
80  TimeLimit::FromParameters(parameters_);
81  return SolveWithTimeLimit(time_limit.get());
82 }
83 
85  CHECK(time_limit != nullptr);
86  SCOPED_TIME_STAT(&stats_);
87 
88  absl::Status valid = sat::ValidateBooleanProblem(problem_);
89  if (!valid.ok()) {
90  LOG(ERROR) << "Invalid Boolean problem: " << valid.message();
92  }
93 
94  UpdateParameters();
95 
96  return parameters_.number_of_solvers() > 1
97  ? InternalMultithreadSolver(time_limit)
98  : InternalMonothreadSolver(time_limit);
99 }
100 
101 BopSolveStatus BopSolver::InternalMonothreadSolver(TimeLimit* time_limit) {
102  CHECK(time_limit != nullptr);
103  LearnedInfo learned_info(problem_state_.original_problem());
104  PortfolioOptimizer optimizer(problem_state_, parameters_,
105  parameters_.solver_optimizer_sets(0),
106  "Portfolio");
107  while (!time_limit->LimitReached()) {
108  const BopOptimizerBase::Status optimization_status = optimizer.Optimize(
109  parameters_, problem_state_, &learned_info, time_limit);
110  problem_state_.MergeLearnedInfo(learned_info, optimization_status);
111 
112  if (optimization_status == BopOptimizerBase::SOLUTION_FOUND) {
113  CHECK(problem_state_.solution().IsFeasible());
114  VLOG(1) << problem_state_.solution().GetScaledCost()
115  << " New solution! ";
116  }
117 
118  if (problem_state_.IsOptimal()) {
119  CHECK(problem_state_.solution().IsFeasible());
121  } else if (problem_state_.IsInfeasible()) {
123  }
124 
125  if (optimization_status == BopOptimizerBase::ABORT) {
126  break;
127  }
128  learned_info.Clear();
129  }
130 
131  return problem_state_.solution().IsFeasible()
134 }
135 
136 BopSolveStatus BopSolver::InternalMultithreadSolver(TimeLimit* time_limit) {
137  CHECK(time_limit != nullptr);
138  // Not implemented.
140 }
141 
143  std::unique_ptr<TimeLimit> time_limit =
144  TimeLimit::FromParameters(parameters_);
145  return SolveWithTimeLimit(first_solution, time_limit.get());
146 }
147 
150  SCOPED_TIME_STAT(&stats_);
151 
152  if (first_solution.IsFeasible()) {
153  VLOG(1) << "First solution is feasible.";
154  LearnedInfo learned_info(problem_);
155  learned_info.solution = first_solution;
156  if (problem_state_.MergeLearnedInfo(learned_info,
158  problem_state_.IsOptimal()) {
160  }
161  } else {
162  VLOG(1)
163  << "First solution is infeasible. Using it as assignment preference.";
164  std::vector<bool> assignment_preference;
165  for (int i = 0; i < first_solution.Size(); ++i) {
166  assignment_preference.push_back(first_solution.Value(VariableIndex(i)));
167  }
168  problem_state_.set_assignment_preference(assignment_preference);
169  }
171 }
172 
175  problem_, sat::Coefficient(problem_state_.lower_bound()));
176 }
177 
178 double BopSolver::GetScaledGap() const {
179  return 100.0 *
180  std::abs(problem_state_.solution().GetScaledCost() -
181  GetScaledBestBound()) /
182  std::abs(problem_state_.solution().GetScaledCost());
183 }
184 
185 void BopSolver::UpdateParameters() {
186  if (parameters_.solver_optimizer_sets_size() == 0) {
187  // No user defined optimizers, use the default string to define the
188  // behavior.
189  CHECK(::google::protobuf::TextFormat::ParseFromString(
190  parameters_.default_solver_optimizer_sets(),
191  parameters_.add_solver_optimizer_sets()));
192  }
193 
194  problem_state_.SetParameters(parameters_);
195 }
196 } // namespace bop
197 } // namespace operations_research
bop_fs.h
operations_research::bop::BopSolveStatus::INVALID_PROBLEM
@ INVALID_PROBLEM
operations_research::bop::BopOptimizerBase::CONTINUE
@ CONTINUE
Definition: bop_base.h:76
operations_research::glop::DenseRow
StrictITIVector< ColIndex, Fractional > DenseRow
Definition: lp_types.h:299
operations_research::sat::ValidateBooleanProblem
absl::Status ValidateBooleanProblem(const LinearBooleanProblem &problem)
Definition: boolean_problem.cc:131
operations_research::bop::ProblemState::solution
const BopSolution & solution() const
Definition: bop_base.h:193
complete_optimizer.h
IF_STATS_ENABLED
#define IF_STATS_ENABLED(instructions)
Definition: stats.h:430
operations_research::bop::BopSolver::Solve
BopSolveStatus Solve()
Definition: bop_solver.cc:78
operations_research::bop::ProblemState::lower_bound
int64 lower_bound() const
Definition: bop_base.h:206
operations_research::bop::BopOptimizerBase::OPTIMAL_SOLUTION_FOUND
@ OPTIMAL_SOLUTION_FOUND
Definition: bop_base.h:62
operations_research::bop::BopSolution::Value
bool Value(VariableIndex var) const
Definition: bop_solution.h:42
operations_research::bop::BopSolver::~BopSolver
virtual ~BopSolver()
Definition: bop_solver.cc:76
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::BopOptimizerBase::ABORT
@ ABORT
Definition: bop_base.h:79
bop_portfolio.h
sat_solver.h
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::ProblemState::IsInfeasible
bool IsInfeasible() const
Definition: bop_base.h:168
SCOPED_TIME_STAT
#define SCOPED_TIME_STAT(stats)
Definition: stats.h:431
operations_research::bop::ProblemState::SetParameters
void SetParameters(const BopParameters &parameters)
Definition: bop_base.h:116
operations_research::bop::BopSolver::SolveWithTimeLimit
BopSolveStatus SolveWithTimeLimit(TimeLimit *time_limit)
Definition: bop_solver.cc:84
operations_research::bop::BopSolver::GetScaledGap
double GetScaledGap() const
Definition: bop_solver.cc:178
time_limit
SharedTimeLimit * time_limit
Definition: cp_model_solver.cc:2025
bop_solver.h
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::BopSolveStatus::INFEASIBLE_PROBLEM
@ INFEASIBLE_PROBLEM
operations_research::bop::BopSolveStatus::NO_SOLUTION_FOUND
@ NO_SOLUTION_FOUND
operations_research::sat::AddOffsetAndScaleObjectiveValue
double AddOffsetAndScaleObjectiveValue(const LinearBooleanProblem &problem, Coefficient v)
Definition: boolean_problem.h:39
bop_util.h
operations_research::bop::BopOptimizerBase::SOLUTION_FOUND
@ SOLUTION_FOUND
Definition: bop_base.h:63
operations_research::bop::BopSolveStatus::FEASIBLE_SOLUTION_FOUND
@ FEASIBLE_SOLUTION_FOUND
operations_research::bop::BopSolution::Size
size_t Size() const
Definition: bop_solution.h:41
operations_research::bop::ProblemState::MergeLearnedInfo
bool MergeLearnedInfo(const LearnedInfo &learned_info, BopOptimizerBase::Status optimization_status)
Definition: bop_base.cc:90
operations_research::bop::BopSolution::IsFeasible
bool IsFeasible() const
Definition: bop_solution.h:68
operations_research::bop::ProblemState::set_assignment_preference
void set_assignment_preference(const std::vector< bool > &a)
Definition: bop_base.h:124
operations_research::bop::BopSolution
Definition: bop_solution.h:31
operations_research::bop::BopSolution::GetScaledCost
double GetScaledCost() const
Definition: bop_solution.h:60
lp_print_utils.h
bop_ls.h
stl_util.h
operations_research::bop::LearnedInfo::solution
BopSolution solution
Definition: bop_base.h:266
operations_research::bop::ProblemState::IsOptimal
bool IsOptimal() const
Definition: bop_base.h:163
operations_research::bop::PortfolioOptimizer
Definition: bop_portfolio.h:60
operations_research::StatsGroup::StatString
std::string StatString() const
Definition: stats.cc:71
lp_utils.h
boolean_problem.h
operations_research::TimeLimit::FromParameters
static std::unique_ptr< TimeLimit > FromParameters(const Parameters &parameters)
Creates a time limit object initialized from an object that provides methods max_time_in_seconds() an...
Definition: time_limit.h:159
bop_lns.h
operations_research::bop::BopSolveStatus
BopSolveStatus
Definition: bop_types.h:31
commandlineflags.h
operations_research::bop::BopSolver::GetScaledBestBound
double GetScaledBestBound() const
Definition: bop_solver.cc:173
operations_research::bop::BopOptimizerBase::Status
Status
Definition: bop_base.h:61
bitset.h
operations_research::bop::BopSolver::BopSolver
BopSolver(const sat::LinearBooleanProblem &problem)
Definition: bop_solver.cc:68
operations_research::bop::BopSolveStatus::OPTIMAL_SOLUTION_FOUND
@ OPTIMAL_SOLUTION_FOUND
lp_solver.h