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