Google OR-Tools v9.11
a fast and portable software suite for combinatorial optimization
Loading...
Searching...
No Matches
bop_lns.h
Go to the documentation of this file.
1// Copyright 2010-2024 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 <memory>
19#include <vector>
20
21#include "absl/random/bit_gen_ref.h"
22#include "absl/strings/string_view.h"
25#include "ortools/bop/bop_parameters.pb.h"
28#include "ortools/sat/boolean_problem.pb.h"
31
32namespace operations_research {
33namespace bop {
34
35// Uses SAT to solve the full problem under the constraint that the new solution
36// should be under a given Hamming distance of the current solution.
38 public:
39 BopCompleteLNSOptimizer(absl::string_view name,
40 const BopConstraintTerms& objective_terms);
42
43 private:
44 bool ShouldBeRun(const ProblemState& problem_state) const final;
45 Status Optimize(const BopParameters& parameters,
46 const ProblemState& problem_state, LearnedInfo* learned_info,
47 TimeLimit* time_limit) final;
48
49 BopOptimizerBase::Status SynchronizeIfNeeded(
50 const ProblemState& problem_state, int num_relaxed_vars);
51
52 int64_t state_update_stamp_;
53 std::unique_ptr<sat::SatSolver> sat_solver_;
54 const BopConstraintTerms& objective_terms_;
55};
56
57// Interface of the different LNS neighborhood generation algorithm.
58//
59// NOTE(user): Using a sat_propagator as the output of the algorithm allows for
60// a really simple and efficient interface for the generator that relies on it.
61// However, if a generator doesn't rely on it at all, it may slow down a bit the
62// code (to investigate). If this happens, we will probably need another
63// function here and a way to select between which one to call.
65 public:
67 virtual ~NeighborhoodGenerator() = default;
68
69 // Interface for the neighborhood generation.
70 //
71 // The difficulty will be in [0, 1] and is related to the asked neighborhood
72 // size (and thus local problem difficulty). A difficulty of 0.0 means empty
73 // neighborhood and a difficulty of 1.0 means the full problem. The algorithm
74 // should try to generate an neighborhood according to this difficulty, which
75 // will be dynamically adjusted depending on whether or not we can solve the
76 // subproblem.
77 //
78 // The given sat_propagator will be reset and then configured so that all the
79 // variables propagated on its trail should be fixed. That is, the
80 // neighborhood will correspond to the unassigned variables in the
81 // sat_propagator. Note that sat_propagator_.IsModelUnsat() will be checked
82 // after this is called so it is okay to abort if this happens.
83 //
84 // Preconditions:
85 // - The given sat_propagator_ should have the current problem loaded (with
86 // the constraint to find a better solution that any current solution).
87 // - The problem state must contains a feasible solution.
88 virtual void GenerateNeighborhood(const ProblemState& problem_state,
89 double difficulty,
90 sat::SatSolver* sat_propagator) = 0;
91};
92
93// A generic LNS optimizer which generates neighborhoods according to the given
94// NeighborhoodGenerator and automatically adapt the neighborhood size depending
95// on how easy it is to solve the associated problem.
97 public:
98 // Takes ownership of the given neighborhood_generator.
99 // The sat_propagator is assumed to contains the current problem.
100 BopAdaptiveLNSOptimizer(absl::string_view name, bool use_lp_to_guide_sat,
101 NeighborhoodGenerator* neighborhood_generator,
102 sat::SatSolver* sat_propagator);
104
105 private:
106 bool ShouldBeRun(const ProblemState& problem_state) const final;
107 Status Optimize(const BopParameters& parameters,
108 const ProblemState& problem_state, LearnedInfo* learned_info,
109 TimeLimit* time_limit) final;
110
111 const bool use_lp_to_guide_sat_;
112 std::unique_ptr<NeighborhoodGenerator> neighborhood_generator_;
113 sat::SatSolver* const sat_propagator_;
114
115 // Adaptive neighborhood size logic.
116 // The values are kept from one run to the next.
117 LubyAdaptiveParameterValue adaptive_difficulty_;
118};
119
120// Generates a neighborhood by randomly fixing a subset of the objective
121// variables that are currently at their lower cost.
123 public:
125 absl::BitGenRef random)
126 : objective_terms_(*objective_terms), random_(random) {}
128
129 private:
130 void GenerateNeighborhood(const ProblemState& problem_state,
131 double difficulty,
132 sat::SatSolver* sat_propagator) final;
133 const BopConstraintTerms& objective_terms_;
134 absl::BitGenRef random_;
135};
136
137// Generates a neighborhood by randomly selecting a subset of constraints and
138// fixing the objective variables that are currently at their lower cost and
139// not in the given subset of constraints.
141 public:
143 absl::BitGenRef random)
144 : objective_terms_(*objective_terms), random_(random) {}
146
147 private:
148 void GenerateNeighborhood(const ProblemState& problem_state,
149 double difficulty,
150 sat::SatSolver* sat_propagator) final;
151 const BopConstraintTerms& objective_terms_;
152 absl::BitGenRef random_;
153};
154
155// Generates a neighborhood by taking a random local neighborhood in an
156// undirected graph where the nodes are the variables and two nodes are linked
157// if they appear in the same constraint.
159 public:
160 RelationGraphBasedNeighborhood(const sat::LinearBooleanProblem& problem,
161 absl::BitGenRef random);
163
164 private:
165 void GenerateNeighborhood(const ProblemState& problem_state,
166 double difficulty,
167 sat::SatSolver* sat_propagator) final;
168
169 // TODO(user): reuse by_variable_matrix_ from the LS? Note however than we
170 // don't need the coefficients here.
171 util_intops::StrongVector<VariableIndex, std::vector<ConstraintIndex>>
172 columns_;
173 absl::BitGenRef random_;
174};
175
176} // namespace bop
177} // namespace operations_research
178#endif // OR_TOOLS_BOP_BOP_LNS_H_
BopCompleteLNSOptimizer(absl::string_view name, const BopConstraintTerms &objective_terms)
Definition bop_lns.cc:73
const std::string & name() const
Returns the name given at construction.
Definition bop_base.h:54
ConstraintBasedNeighborhood(const BopConstraintTerms *objective_terms, absl::BitGenRef random)
Definition bop_lns.h:142
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:124
SatParameters parameters
const std::string name
A name for logging purposes.
time_limit
Definition solve.cc:22
In SWIG mode, we don't want anything besides these top-level includes.
STL namespace.