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