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