OR-Tools  9.3
bop_lns.h
Go to the documentation of this file.
1// Copyright 2010-2021 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#ifndef OR_TOOLS_BOP_BOP_LNS_H_
15#define OR_TOOLS_BOP_BOP_LNS_H_
16
17#include <cstdint>
18#include <string>
19#include <vector>
20
24#include "ortools/base/macros.h"
27#include "ortools/bop/bop_parameters.pb.h"
32#include "ortools/sat/boolean_problem.pb.h"
34#include "ortools/util/stats.h"
36
37namespace operations_research {
38namespace bop {
39
40// Uses SAT to solve the full problem under the constraint that the new solution
41// should be under a given Hamming distance of the current solution.
43 public:
44 BopCompleteLNSOptimizer(const std::string& name,
45 const BopConstraintTerms& objective_terms);
47
48 private:
49 bool ShouldBeRun(const ProblemState& problem_state) const final;
50 Status Optimize(const BopParameters& parameters,
51 const ProblemState& problem_state, LearnedInfo* learned_info,
52 TimeLimit* time_limit) final;
53
54 BopOptimizerBase::Status SynchronizeIfNeeded(
55 const ProblemState& problem_state, int num_relaxed_vars);
56
57 int64_t state_update_stamp_;
58 std::unique_ptr<sat::SatSolver> sat_solver_;
59 const BopConstraintTerms& objective_terms_;
60};
61
62// Interface of the different LNS neighborhood generation algorithm.
63//
64// NOTE(user): Using a sat_propagator as the output of the algorithm allows for
65// a really simple and efficient interface for the generator that relies on it.
66// However, if a generator doesn't rely on it at all, it may slow down a bit the
67// code (to investigate). If this happens, we will probably need another
68// function here and a way to select between which one to call.
70 public:
73
74 // Interface for the neighborhood generation.
75 //
76 // The difficulty will be in [0, 1] and is related to the asked neighborhood
77 // size (and thus local problem difficulty). A difficulty of 0.0 means empty
78 // neighborhood and a difficulty of 1.0 means the full problem. The algorithm
79 // should try to generate an neighborhood according to this difficulty, which
80 // will be dynamically adjusted depending on whether or not we can solve the
81 // subproblem.
82 //
83 // The given sat_propagator will be reset and then configured so that all the
84 // variables propagated on its trail should be fixed. That is, the
85 // neighborhood will correspond to the unassigned variables in the
86 // sat_propagator. Note that sat_propagator_.IsModelUnsat() will be checked
87 // after this is called so it is okay to abort if this happens.
88 //
89 // Preconditions:
90 // - The given sat_propagator_ should have the current problem loaded (with
91 // the constraint to find a better solution that any current solution).
92 // - The problem state must contains a feasible solution.
93 virtual void GenerateNeighborhood(const ProblemState& problem_state,
94 double difficulty,
95 sat::SatSolver* sat_propagator) = 0;
96};
97
98// A generic LNS optimizer which generates neighborhoods according to the given
99// NeighborhoodGenerator and automatically adapt the neighborhood size depending
100// on how easy it is to solve the associated problem.
102 public:
103 // Takes ownership of the given neighborhood_generator.
104 // The sat_propagator is assumed to contains the current problem.
105 BopAdaptiveLNSOptimizer(const std::string& name, bool use_lp_to_guide_sat,
106 NeighborhoodGenerator* neighborhood_generator,
107 sat::SatSolver* sat_propagator);
109
110 private:
111 bool ShouldBeRun(const ProblemState& problem_state) const final;
112 Status Optimize(const BopParameters& parameters,
113 const ProblemState& problem_state, LearnedInfo* learned_info,
114 TimeLimit* time_limit) final;
115
116 const bool use_lp_to_guide_sat_;
117 std::unique_ptr<NeighborhoodGenerator> neighborhood_generator_;
118 sat::SatSolver* const sat_propagator_;
119
120 // Adaptive neighborhood size logic.
121 // The values are kept from one run to the next.
122 LubyAdaptiveParameterValue adaptive_difficulty_;
123};
124
125// Generates a neighborhood by randomly fixing a subset of the objective
126// variables that are currently at their lower cost.
128 public:
130 absl::BitGenRef random)
131 : objective_terms_(*objective_terms), random_(random) {}
133
134 private:
135 void GenerateNeighborhood(const ProblemState& problem_state,
136 double difficulty,
137 sat::SatSolver* sat_propagator) final;
138 const BopConstraintTerms& objective_terms_;
139 absl::BitGenRef random_;
140};
141
142// Generates a neighborhood by randomly selecting a subset of constraints and
143// fixing the objective variables that are currently at their lower cost and
144// not in the given subset of constraints.
146 public:
148 absl::BitGenRef random)
149 : objective_terms_(*objective_terms), random_(random) {}
151
152 private:
153 void GenerateNeighborhood(const ProblemState& problem_state,
154 double difficulty,
155 sat::SatSolver* sat_propagator) final;
156 const BopConstraintTerms& objective_terms_;
157 absl::BitGenRef random_;
158};
159
160// Generates a neighborhood by taking a random local neighborhood in an
161// undirected graph where the nodes are the variables and two nodes are linked
162// if they appear in the same constraint.
164 public:
165 RelationGraphBasedNeighborhood(const sat::LinearBooleanProblem& problem,
166 absl::BitGenRef random);
168
169 private:
170 void GenerateNeighborhood(const ProblemState& problem_state,
171 double difficulty,
172 sat::SatSolver* sat_propagator) final;
173
174 // TODO(user): reuse by_variable_matrix_ from the LS? Note however than we
175 // don't need the coefficients here.
177 absl::BitGenRef random_;
178};
179
180} // namespace bop
181} // namespace operations_research
182#endif // OR_TOOLS_BOP_BOP_LNS_H_
A simple class to enforce both an elapsed time limit and a deterministic time limit in the same threa...
Definition: time_limit.h:106
BopAdaptiveLNSOptimizer(const std::string &name, bool use_lp_to_guide_sat, NeighborhoodGenerator *neighborhood_generator, sat::SatSolver *sat_propagator)
Definition: bop_lns.cc:213
BopCompleteLNSOptimizer(const std::string &name, const BopConstraintTerms &objective_terms)
Definition: bop_lns.cc:57
const std::string & name() const
Definition: bop_base.h:49
ConstraintBasedNeighborhood(const BopConstraintTerms *objective_terms, absl::BitGenRef random)
Definition: bop_lns.h:147
virtual void GenerateNeighborhood(const ProblemState &problem_state, double difficulty, sat::SatSolver *sat_propagator)=0
ObjectiveBasedNeighborhood(const BopConstraintTerms *objective_terms, absl::BitGenRef random)
Definition: bop_lns.h:129
RelationGraphBasedNeighborhood(const sat::LinearBooleanProblem &problem, absl::BitGenRef random)
Definition: bop_lns.cc:508
SatParameters parameters
ModelSharedTimeLimit * time_limit
Collection of objects used to extend the Constraint Solver library.