OR-Tools  9.1
cp_model_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_SAT_CP_MODEL_LNS_H_
15#define OR_TOOLS_SAT_CP_MODEL_LNS_H_
16
17#include <cstdint>
18#include <vector>
19
20#include "absl/container/flat_hash_map.h"
21#include "absl/random/bit_gen_ref.h"
22#include "absl/synchronization/mutex.h"
23#include "absl/types/span.h"
26#include "ortools/sat/model.h"
30
31namespace operations_research {
32namespace sat {
33
34// Neighborhood returned by Neighborhood generators.
36 // True if neighborhood generator was able to generate a neighborhood.
37 bool is_generated = false;
38
39 // True if an optimal solution to the neighborhood is also an optimal solution
40 // to the original model.
41 bool is_reduced = false;
42
43 // Specification of the delta between the initial model and the lns fragment.
44 // The delta will contains all variables from the initial model, potentially
45 // with updated domains.
46 // It can contains new variables and new constraints, and solution hinting.
48 std::vector<int> constraints_to_ignore;
49
50 // Neighborhood Id. Used to identify the neighborhood by a generator.
51 // Currently only used by WeightedRandomRelaxationNeighborhoodGenerator.
52 // TODO(user): Make sure that the id is unique for each generated
53 // neighborhood for each generator.
54 int64_t id = 0;
55
56 // Used for identifying the source of the neighborhood if it is generated
57 // using solution repositories.
58 std::string source_info = "";
59};
60
61// Contains pre-computed information about a given CpModelProto that is meant
62// to be used to generate LNS neighborhood. This class can be shared between
63// more than one generator in order to reduce memory usage.
64//
65// Note that its implement the SubSolver interface to be able to Synchronize()
66// the bounds of the base problem with the external world.
68 public:
72 SharedTimeLimit* shared_time_limit = nullptr,
73 SharedBoundsManager* shared_bounds = nullptr);
74
75 // SubSolver interface.
76 bool TaskIsAvailable() override { return false; }
77 std::function<void()> GenerateTask(int64_t task_id) override { return {}; }
78 void Synchronize() override;
79
80 // Returns the LNS fragment where the given variables are fixed to the value
81 // they take in the given solution.
83 const CpSolverResponse& initial_solution,
84 const absl::flat_hash_set<int>& variables_to_fix) const;
85
86 // Returns the neighborhood where the given constraints are removed.
88 const std::vector<int>& constraints_to_remove) const;
89
90 // Returns the LNS fragment which will relax all inactive variables and all
91 // variables in relaxed_variables.
93 const CpSolverResponse& initial_solution,
94 const std::vector<int>& relaxed_variables) const;
95
96 // Returns a trivial model by fixing all active variables to the initial
97 // solution values.
98 Neighborhood FixAllVariables(const CpSolverResponse& initial_solution) const;
99
100 // Return a neighborhood that correspond to the full problem.
102
103 // Indicate that the generator failed to generated a neighborhood.
105
106 // Copies all variables from the in_model to the delta model of the
107 // neighborhood. For all variables in fixed_variable_set, the domain will be
108 // overwritten with the value stored in the initial solution.
109 //
110 // It returns true iff all fixed values are compatible with the domain of the
111 // corresponding variables in the in_model.
112 // TODO(user): We should probably make sure that this can never happen, or
113 // relax the bounds so that we can try to improve the initial solution rather
114 // than just aborting early.
115 bool CopyAndFixVariables(const CpModelProto& source_model,
116 const absl::flat_hash_set<int>& fixed_variables_set,
117 const CpSolverResponse& initial_solution,
118 CpModelProto* output_model) const;
119
120 // Adds solution hinting to the neighborhood from the value of the initial
121 // solution.
122 void AddSolutionHinting(const CpSolverResponse& initial_solution,
124
125 // Indicates if the variable can be frozen. It happens if the variable is non
126 // constant, and if it is a decision variable, or if
127 // focus_on_decision_variables is false.
128 bool IsActive(int var) const ABSL_SHARED_LOCKS_REQUIRED(graph_mutex_);
129
130 // Returns the list of "active" variables.
131 std::vector<int> ActiveVariables() const {
132 std::vector<int> result;
133 absl::ReaderMutexLock lock(&graph_mutex_);
134 result = active_variables_;
135 return result;
136 }
137
138 int NumActiveVariables() const {
139 absl::ReaderMutexLock lock(&graph_mutex_);
140 return active_variables_.size();
141 }
142
143 bool DifficultyMeansFullNeighborhood(double difficulty) const {
144 absl::ReaderMutexLock lock(&graph_mutex_);
145 const int target_size = std::ceil(difficulty * active_variables_.size());
146 return target_size == active_variables_.size();
147 }
148
149 // Returns the vector of active variables. The graph_mutex_ must be
150 // locked before calling this method.
151 const std::vector<int>& ActiveVariablesWhileHoldingLock() const
152 ABSL_SHARED_LOCKS_REQUIRED(graph_mutex_) {
153 return active_variables_;
154 }
155
156 // Constraints <-> Variables graph.
157 // Note that only non-constant variable are listed here.
158 const std::vector<std::vector<int>>& ConstraintToVar() const
159 ABSL_SHARED_LOCKS_REQUIRED(graph_mutex_) {
160 return constraint_to_var_;
161 }
162 const std::vector<std::vector<int>>& VarToConstraint() const
163 ABSL_SHARED_LOCKS_REQUIRED(graph_mutex_) {
164 return var_to_constraint_;
165 }
166
167 // Returns all the constraints indices of a given type.
168 const absl::Span<const int> TypeToConstraints(
170 if (type >= type_to_constraints_.size()) return {};
171 return absl::MakeSpan(type_to_constraints_[type]);
172 }
173
174 // Returns the list of indices of active interval constraints according
175 // to the initial_solution and the parameter lns_focus_on_performed_intervals.
176 // If true, this method returns the list of performed intervals in the
177 // solution. If false, it returns all intervals of the model.
178 std::vector<int> GetActiveIntervals(
179 const CpSolverResponse& initial_solution) const;
180
181 // Returns one sub-vector per circuit or per single vehicle ciruit in a routes
182 // constraints. Each circuit is non empty, and does not contain any
183 // self-looping arcs. Path are sorted, starting from the arc with the lowest
184 // tail index, and going in sequence up to the last arc before the circuit is
185 // closed. Each entry correspond to the arc literal on the circuit.
186 std::vector<std::vector<int>> GetRoutingPaths(
187 const CpSolverResponse& initial_solution) const;
188
189 // The initial problem.
190 // Note that the domain of the variables are not updated here.
191 const CpModelProto& ModelProto() const { return model_proto_; }
192 const SatParameters& Parameters() const { return parameters_; }
193
195 return *shared_response_;
196 }
197
198 // TODO(user): Refactor the class to be thread-safe instead, it should be
199 // safer and more easily maintenable. Some complication with accessing the
200 // variable<->constraint graph efficiently though.
201
202 // Note: This mutex needs to be public for thread annotations.
203 mutable absl::Mutex graph_mutex_;
204
205 // TODO(user): Display LNS statistics through the StatisticsString()
206 // method.
207
208 private:
209 // Precompute stuff that will never change. During the execution, only the
210 // domain of the variable will change, so data that only depends on the
211 // constraints need to be computed just once.
212 void InitializeHelperData();
213
214 // Recompute most of the class member. This needs to be called when the
215 // domains of the variables are updated.
216 void RecomputeHelperData();
217
218 // Indicates if a variable is fixed in the model.
219 bool IsConstant(int var) const ABSL_SHARED_LOCKS_REQUIRED(domain_mutex_);
220
221 const SatParameters& parameters_;
222 const CpModelProto& model_proto_;
223 int shared_bounds_id_;
224 SharedTimeLimit* shared_time_limit_;
225 SharedBoundsManager* shared_bounds_;
226 SharedResponseManager* shared_response_;
227 SharedRelaxationSolutionRepository* shared_relaxation_solutions_;
228
229 // This proto will only contain the field variables() with an updated version
230 // of the domains compared to model_proto_.variables(). We do it like this to
231 // reduce the memory footprint of the helper when the model is large.
232 //
233 // TODO(user): Use custom domain repository rather than a proto?
234 CpModelProto model_proto_with_only_variables_ ABSL_GUARDED_BY(domain_mutex_);
235
236 // Constraints by types.
237 std::vector<std::vector<int>> type_to_constraints_;
238
239 // Variable-Constraint graph.
240 std::vector<std::vector<int>> constraint_to_var_
241 ABSL_GUARDED_BY(graph_mutex_);
242 std::vector<std::vector<int>> var_to_constraint_
243 ABSL_GUARDED_BY(graph_mutex_);
244
245 // The set of active variables, that is the list of non constant variables if
246 // parameters_.focus_on_decision_variables() is false, or the list of non
247 // constant decision variables otherwise. It is stored both as a list and as a
248 // set (using a Boolean vector).
249 std::vector<bool> active_variables_set_ ABSL_GUARDED_BY(graph_mutex_);
250 std::vector<int> active_variables_ ABSL_GUARDED_BY(graph_mutex_);
251
252 mutable absl::Mutex domain_mutex_;
253};
254
255// Base class for a CpModelProto neighborhood generator.
257 public:
258 NeighborhoodGenerator(const std::string& name,
259 NeighborhoodGeneratorHelper const* helper)
260 : name_(name), helper_(*helper), difficulty_(0.5) {}
262
263 // Generates a "local" subproblem for the given seed.
264 //
265 // The difficulty will be in [0, 1] and is related to the asked neighborhood
266 // size (and thus local problem difficulty). A difficulty of 0.0 means empty
267 // neighborhood and a difficulty of 1.0 means the full problem. The algorithm
268 // should try to generate a neighborhood according to this difficulty which
269 // will be dynamically adjusted depending on whether or not we can solve the
270 // subproblem in a given time limit.
271 //
272 // The given initial_solution should contain a feasible solution to the
273 // initial CpModelProto given to this class. Any solution to the returned
274 // CPModelProto should also be valid solution to the same initial model.
275 //
276 // This function should be thread-safe.
277 virtual Neighborhood Generate(const CpSolverResponse& initial_solution,
278 double difficulty, absl::BitGenRef random) = 0;
279
280 // Returns true if the neighborhood generator can generate a neighborhood.
281 virtual bool ReadyToGenerate() const;
282
283 // Returns true if the neighborhood generator generates relaxation of the
284 // given problem.
285 virtual bool IsRelaxationGenerator() const { return false; }
286
287 // Uses UCB1 algorithm to compute the score (Multi armed bandit problem).
288 // Details are at
289 // https://lilianweng.github.io/lil-log/2018/01/23/the-multi-armed-bandit-problem-and-its-solutions.html.
290 // 'total_num_calls' should be the sum of calls across all generators part of
291 // the multi armed bandit problem.
292 // If the generator is called less than 10 times then the method returns
293 // infinity as score in order to get more data about the generator
294 // performance.
295 double GetUCBScore(int64_t total_num_calls) const;
296
297 // Adds solve data about one "solved" neighborhood.
298 struct SolveData {
299 // Neighborhood Id. Used to identify the neighborhood by a generator.
300 // Currently only used by WeightedRandomRelaxationNeighborhoodGenerator.
301 int64_t neighborhood_id = 0;
302
303 // The status of the sub-solve.
305
306 // The difficulty when this neighborhood was generated.
307 double difficulty = 0.0;
308
309 // The determinitic time limit given to the solver for this neighborhood.
311
312 // The time it took to solve this neighborhood.
313 double deterministic_time = 0.0;
314
315 // Objective information. These only refer to the "internal" objective
316 // without scaling or offset so we are exact and it is always in the
317 // minimization direction.
318 // - The initial best objective is the one of the best known solution at the
319 // time the neighborhood was generated.
320 // - The base objective is the one of the base solution from which this
321 // neighborhood was generated.
322 // - The new objective is the objective of the best solution found by
323 // solving the neighborhood.
324 IntegerValue initial_best_objective = IntegerValue(0);
325 IntegerValue base_objective = IntegerValue(0);
326 IntegerValue new_objective = IntegerValue(0);
327
328 // Bounds data is only used by relaxation neighborhoods.
329 IntegerValue initial_best_objective_bound = IntegerValue(0);
330 IntegerValue new_objective_bound = IntegerValue(0);
331
332 // This is just used to construct a deterministic order for the updates.
333 bool operator<(const SolveData& o) const {
334 return std::tie(status, difficulty, deterministic_limit,
339 std::tie(o.status, o.difficulty, o.deterministic_limit,
344 }
345 };
347 absl::MutexLock mutex_lock(&generator_mutex_);
348 solve_data_.push_back(data);
349 }
350
351 // Process all the recently added solve data and update this generator
352 // score and difficulty.
353 void Synchronize();
354
355 // Returns a short description of the generator.
356 std::string name() const { return name_; }
357
358 // Number of times this generator was called.
359 int64_t num_calls() const {
360 absl::MutexLock mutex_lock(&generator_mutex_);
361 return num_calls_;
362 }
363
364 // Number of time the neighborhood was fully solved (OPTIMAL/INFEASIBLE).
365 int64_t num_fully_solved_calls() const {
366 absl::MutexLock mutex_lock(&generator_mutex_);
367 return num_fully_solved_calls_;
368 }
369
370 // The current difficulty of this generator
371 double difficulty() const {
372 absl::MutexLock mutex_lock(&generator_mutex_);
373 return difficulty_.value();
374 }
375
376 // The current time limit that the sub-solve should use on this generator.
377 double deterministic_limit() const {
378 absl::MutexLock mutex_lock(&generator_mutex_);
379 return deterministic_limit_;
380 }
381
382 // The sum of the deterministic time spent in this generator.
383 double deterministic_time() const {
384 absl::MutexLock mutex_lock(&generator_mutex_);
385 return deterministic_time_;
386 }
387
388 protected:
389 // Triggered with each call to Synchronize() for each recently added
390 // SolveData. This is meant to be used for processing feedbacks by specific
391 // neighborhood generators to adjust the neighborhood generation process.
392 virtual void AdditionalProcessingOnSynchronize(const SolveData& solve_data) {}
393
394 const std::string name_;
396 mutable absl::Mutex generator_mutex_;
397
398 private:
399 std::vector<SolveData> solve_data_;
400
401 // Current parameters to be used when generating/solving a neighborhood with
402 // this generator. Only updated on Synchronize().
403 AdaptiveParameterValue difficulty_;
404 double deterministic_limit_ = 0.1;
405
406 // Current statistics of the last solved neighborhood.
407 // Only updated on Synchronize().
408 int64_t num_calls_ = 0;
409 int64_t num_fully_solved_calls_ = 0;
410 int64_t num_consecutive_non_improving_calls_ = 0;
411 double deterministic_time_ = 0.0;
412 double current_average_ = 0.0;
413};
414
415// Pick a random subset of variables.
417 public:
419 NeighborhoodGeneratorHelper const* helper, const std::string& name)
420 : NeighborhoodGenerator(name, helper) {}
421 Neighborhood Generate(const CpSolverResponse& initial_solution,
422 double difficulty, absl::BitGenRef random) final;
423};
424
425// Pick a random subset of constraints and relax all the variables of these
426// constraints. Note that to satisfy the difficulty, we might not relax all the
427// variable of the "last" constraint.
429 public:
431 NeighborhoodGeneratorHelper const* helper, const std::string& name)
432 : NeighborhoodGenerator(name, helper) {}
433 Neighborhood Generate(const CpSolverResponse& initial_solution,
434 double difficulty, absl::BitGenRef random) final;
435};
436
437// Pick a random subset of variables that are constructed by a BFS in the
438// variable <-> constraint graph. That is, pick a random variable, then all the
439// variable connected by some constraint to the first one, and so on. The
440// variable of the last "level" are selected randomly.
442 public:
444 NeighborhoodGeneratorHelper const* helper, const std::string& name)
445 : NeighborhoodGenerator(name, helper) {}
446 Neighborhood Generate(const CpSolverResponse& initial_solution,
447 double difficulty, absl::BitGenRef random) final;
448};
449
450// Pick a random subset of constraint and relax all of their variables. We are a
451// bit smarter than this because after the first constraint is selected, we only
452// select constraints that share at least one variable with the already selected
453// constraints. The variable from the "last" constraint are selected randomly.
455 public:
457 NeighborhoodGeneratorHelper const* helper, const std::string& name)
458 : NeighborhoodGenerator(name, helper) {}
459 Neighborhood Generate(const CpSolverResponse& initial_solution,
460 double difficulty, absl::BitGenRef random) final;
461};
462
463// Helper method for the scheduling neighborhood generators. Returns the model
464// as neighborhood for the given set of intervals to relax. For each no_overlap
465// constraints, it adds strict relation order between the non-relaxed intervals.
467 const absl::Span<const int> intervals_to_relax,
468 const CpSolverResponse& initial_solution,
469 const NeighborhoodGeneratorHelper& helper);
470
471// Only make sense for scheduling problem. This select a random set of interval
472// of the problem according to the difficulty. Then, for each no_overlap
473// constraints, it adds strict relation order between the non-relaxed intervals.
474//
475// TODO(user): Also deal with cumulative constraint.
477 public:
479 NeighborhoodGeneratorHelper const* helper, const std::string& name)
480 : NeighborhoodGenerator(name, helper) {}
481
482 Neighborhood Generate(const CpSolverResponse& initial_solution,
483 double difficulty, absl::BitGenRef random) final;
484};
485
486// Similar to SchedulingNeighborhoodGenerator except the set of intervals that
487// are relaxed are from a specific random time interval.
489 public:
491 NeighborhoodGeneratorHelper const* helper, const std::string& name)
492 : NeighborhoodGenerator(name, helper) {}
493
494 Neighborhood Generate(const CpSolverResponse& initial_solution,
495 double difficulty, absl::BitGenRef random) final;
496};
497
498// This routing based LNS generator will relax random arcs in all the paths of
499// the circuit or routes constraints.
501 public:
503 const std::string& name)
504 : NeighborhoodGenerator(name, helper) {}
505
506 Neighborhood Generate(const CpSolverResponse& initial_solution,
507 double difficulty, absl::BitGenRef random) final;
508};
509
510// This routing based LNS generator will relax small sequences of arcs randomly
511// chosen in all the paths of the circuit or routes constraints.
513 public:
515 const std::string& name)
516 : NeighborhoodGenerator(name, helper) {}
517
518 Neighborhood Generate(const CpSolverResponse& initial_solution,
519 double difficulty, absl::BitGenRef random) final;
520};
521
522// This routing based LNS generator aims are relaxing one full path, and make
523// some room on the other paths to absorb the nodes of the relaxed path.
524//
525// In order to do so, it will relax the first and the last arc of each path in
526// the circuit or routes constraints. Then it will relax all arc literals in one
527// random path. Then it will relax random arcs in the remaining paths until it
528// reaches the given difficulty.
530 public:
532 NeighborhoodGeneratorHelper const* helper, const std::string& name)
533 : NeighborhoodGenerator(name, helper) {}
534
535 Neighborhood Generate(const CpSolverResponse& initial_solution,
536 double difficulty, absl::BitGenRef random) final;
537};
538
539// Generates a neighborhood by fixing the variables to solutions reported in
540// various repositories. This is inspired from RINS published in "Exploring
541// relaxation induced neighborhoods to improve MIP solutions" 2004 by E. Danna
542// et.
543//
544// If incomplete_solutions is provided, this generates a neighborhood by fixing
545// the variable values to a solution in the SharedIncompleteSolutionManager and
546// ignores the other repositories.
547//
548// Otherwise, if response_manager is not provided, this generates a neighborhood
549// using only the linear/general relaxation values. The domain of the variables
550// are reduced to the integer values around their lp solution/relaxation
551// solution values. This was published in "RENS – The Relaxation Enforced
552// Neighborhood" 2009 by Timo Berthold.
554 public:
556 NeighborhoodGeneratorHelper const* helper,
557 const SharedResponseManager* response_manager,
561 const std::string& name)
562 : NeighborhoodGenerator(name, helper),
563 response_manager_(response_manager),
564 relaxation_solutions_(relaxation_solutions),
565 lp_solutions_(lp_solutions),
566 incomplete_solutions_(incomplete_solutions) {
567 CHECK(lp_solutions_ != nullptr || relaxation_solutions_ != nullptr ||
568 incomplete_solutions != nullptr);
569 }
570
571 // Both initial solution and difficulty values are ignored.
572 Neighborhood Generate(const CpSolverResponse& initial_solution,
573 double difficulty, absl::BitGenRef random) final;
574
575 // Returns true if the required solutions are available.
576 bool ReadyToGenerate() const override;
577
578 private:
579 const SharedResponseManager* response_manager_;
580 const SharedRelaxationSolutionRepository* relaxation_solutions_;
581 const SharedLPSolutionRepository* lp_solutions_;
582 SharedIncompleteSolutionManager* incomplete_solutions_;
583};
584
585// Generates a relaxation of the original model by removing a consecutive span
586// of constraints starting at a random index. The number of constraints removed
587// is in sync with the difficulty passed to the generator.
589 : public NeighborhoodGenerator {
590 public:
592 NeighborhoodGeneratorHelper const* helper, const std::string& name)
593 : NeighborhoodGenerator(name, helper) {}
594 Neighborhood Generate(const CpSolverResponse& initial_solution,
595 double difficulty, absl::BitGenRef random) final;
596
597 bool IsRelaxationGenerator() const override { return true; }
598 bool ReadyToGenerate() const override { return true; }
599};
600
601// Generates a relaxation of the original model by removing some constraints
602// randomly with a given weight for each constraint that controls the
603// probability of constraint getting removed. The number of constraints removed
604// is in sync with the difficulty passed to the generator. Higher weighted
605// constraints are more likely to get removed.
607 : public NeighborhoodGenerator {
608 public:
610 NeighborhoodGeneratorHelper const* helper, const std::string& name);
611
612 // Generates the neighborhood as described above. Also stores the removed
613 // constraints indices for adjusting the weights.
614 Neighborhood Generate(const CpSolverResponse& initial_solution,
615 double difficulty, absl::BitGenRef random) final;
616
617 bool IsRelaxationGenerator() const override { return true; }
618 bool ReadyToGenerate() const override { return true; }
619
620 private:
621 // Adjusts the weights of the constraints removed to get the neighborhood
622 // based on the solve_data.
623 void AdditionalProcessingOnSynchronize(const SolveData& solve_data) override
624 ABSL_EXCLUSIVE_LOCKS_REQUIRED(generator_mutex_);
625
626 // Higher weighted constraints are more likely to get removed.
627 std::vector<double> constraint_weights_;
628 int num_removable_constraints_ = 0;
629
630 // Indices of the removed constraints per generated neighborhood.
631 absl::flat_hash_map<int64_t, std::vector<int>> removed_constraints_
632 ABSL_GUARDED_BY(generator_mutex_);
633
634 // TODO(user): Move this to parent class if other generators start using
635 // feedbacks.
636 int64_t next_available_id_ ABSL_GUARDED_BY(generator_mutex_) = 0;
637};
638
639} // namespace sat
640} // namespace operations_research
641
642#endif // OR_TOOLS_SAT_CP_MODEL_LNS_H_
#define CHECK(condition)
Definition: base/logging.h:491
ConsecutiveConstraintsRelaxationNeighborhoodGenerator(NeighborhoodGeneratorHelper const *helper, const std::string &name)
Definition: cp_model_lns.h:591
Neighborhood Generate(const CpSolverResponse &initial_solution, double difficulty, absl::BitGenRef random) final
Neighborhood Generate(const CpSolverResponse &initial_solution, double difficulty, absl::BitGenRef random) final
ConstraintGraphNeighborhoodGenerator(NeighborhoodGeneratorHelper const *helper, const std::string &name)
Definition: cp_model_lns.h:456
NeighborhoodGeneratorHelper(CpModelProto const *model_proto, SatParameters const *parameters, SharedResponseManager *shared_response, SharedTimeLimit *shared_time_limit=nullptr, SharedBoundsManager *shared_bounds=nullptr)
Definition: cp_model_lns.cc:36
Neighborhood FixAllVariables(const CpSolverResponse &initial_solution) const
const absl::Span< const int > TypeToConstraints(ConstraintProto::ConstraintCase type) const
Definition: cp_model_lns.h:168
Neighborhood FixGivenVariables(const CpSolverResponse &initial_solution, const absl::flat_hash_set< int > &variables_to_fix) const
bool CopyAndFixVariables(const CpModelProto &source_model, const absl::flat_hash_set< int > &fixed_variables_set, const CpSolverResponse &initial_solution, CpModelProto *output_model) const
std::function< void()> GenerateTask(int64_t task_id) override
Definition: cp_model_lns.h:77
bool DifficultyMeansFullNeighborhood(double difficulty) const
Definition: cp_model_lns.h:143
Neighborhood RelaxGivenVariables(const CpSolverResponse &initial_solution, const std::vector< int > &relaxed_variables) const
std::vector< int > GetActiveIntervals(const CpSolverResponse &initial_solution) const
const SharedResponseManager & shared_response() const
Definition: cp_model_lns.h:194
const std::vector< std::vector< int > > & VarToConstraint() const ABSL_SHARED_LOCKS_REQUIRED(graph_mutex_)
Definition: cp_model_lns.h:162
bool IsActive(int var) const ABSL_SHARED_LOCKS_REQUIRED(graph_mutex_)
const std::vector< int > & ActiveVariablesWhileHoldingLock() const ABSL_SHARED_LOCKS_REQUIRED(graph_mutex_)
Definition: cp_model_lns.h:151
Neighborhood RemoveMarkedConstraints(const std::vector< int > &constraints_to_remove) const
void AddSolutionHinting(const CpSolverResponse &initial_solution, CpModelProto *model_proto) const
const std::vector< std::vector< int > > & ConstraintToVar() const ABSL_SHARED_LOCKS_REQUIRED(graph_mutex_)
Definition: cp_model_lns.h:158
std::vector< std::vector< int > > GetRoutingPaths(const CpSolverResponse &initial_solution) const
virtual Neighborhood Generate(const CpSolverResponse &initial_solution, double difficulty, absl::BitGenRef random)=0
double GetUCBScore(int64_t total_num_calls) const
NeighborhoodGenerator(const std::string &name, NeighborhoodGeneratorHelper const *helper)
Definition: cp_model_lns.h:258
virtual void AdditionalProcessingOnSynchronize(const SolveData &solve_data)
Definition: cp_model_lns.h:392
const NeighborhoodGeneratorHelper & helper_
Definition: cp_model_lns.h:395
Neighborhood Generate(const CpSolverResponse &initial_solution, double difficulty, absl::BitGenRef random) final
RelaxRandomConstraintsGenerator(NeighborhoodGeneratorHelper const *helper, const std::string &name)
Definition: cp_model_lns.h:430
Neighborhood Generate(const CpSolverResponse &initial_solution, double difficulty, absl::BitGenRef random) final
RelaxRandomVariablesGenerator(NeighborhoodGeneratorHelper const *helper, const std::string &name)
Definition: cp_model_lns.h:418
RelaxationInducedNeighborhoodGenerator(NeighborhoodGeneratorHelper const *helper, const SharedResponseManager *response_manager, const SharedRelaxationSolutionRepository *relaxation_solutions, const SharedLPSolutionRepository *lp_solutions, SharedIncompleteSolutionManager *incomplete_solutions, const std::string &name)
Definition: cp_model_lns.h:555
Neighborhood Generate(const CpSolverResponse &initial_solution, double difficulty, absl::BitGenRef random) final
Neighborhood Generate(const CpSolverResponse &initial_solution, double difficulty, absl::BitGenRef random) final
RoutingFullPathNeighborhoodGenerator(NeighborhoodGeneratorHelper const *helper, const std::string &name)
Definition: cp_model_lns.h:531
Neighborhood Generate(const CpSolverResponse &initial_solution, double difficulty, absl::BitGenRef random) final
RoutingPathNeighborhoodGenerator(NeighborhoodGeneratorHelper const *helper, const std::string &name)
Definition: cp_model_lns.h:514
RoutingRandomNeighborhoodGenerator(NeighborhoodGeneratorHelper const *helper, const std::string &name)
Definition: cp_model_lns.h:502
Neighborhood Generate(const CpSolverResponse &initial_solution, double difficulty, absl::BitGenRef random) final
SchedulingNeighborhoodGenerator(NeighborhoodGeneratorHelper const *helper, const std::string &name)
Definition: cp_model_lns.h:478
Neighborhood Generate(const CpSolverResponse &initial_solution, double difficulty, absl::BitGenRef random) final
SchedulingTimeWindowNeighborhoodGenerator(NeighborhoodGeneratorHelper const *helper, const std::string &name)
Definition: cp_model_lns.h:490
Neighborhood Generate(const CpSolverResponse &initial_solution, double difficulty, absl::BitGenRef random) final
VariableGraphNeighborhoodGenerator(NeighborhoodGeneratorHelper const *helper, const std::string &name)
Definition: cp_model_lns.h:443
Neighborhood Generate(const CpSolverResponse &initial_solution, double difficulty, absl::BitGenRef random) final
WeightedRandomRelaxationNeighborhoodGenerator(NeighborhoodGeneratorHelper const *helper, const std::string &name)
Neighborhood Generate(const CpSolverResponse &initial_solution, double difficulty, absl::BitGenRef random) final
SatParameters parameters
SharedRelaxationSolutionRepository * relaxation_solutions
SharedLPSolutionRepository * lp_solutions
CpModelProto const * model_proto
SharedIncompleteSolutionManager * incomplete_solutions
IntVar * var
Definition: expr_array.cc:1874
Neighborhood GenerateSchedulingNeighborhoodForRelaxation(const absl::Span< const int > intervals_to_relax, const CpSolverResponse &initial_solution, const NeighborhoodGeneratorHelper &helper)
Collection of objects used to extend the Constraint Solver library.
std::vector< int > constraints_to_ignore
Definition: cp_model_lns.h:48