OR-Tools  9.0
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.
47  CpModelProto delta;
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:
69  NeighborhoodGeneratorHelper(CpModelProto const* model_proto,
70  SatParameters const* parameters,
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 std::vector<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  // Constraints <-> Variables graph.
141  // Note that only non-constant variable are listed here.
142  const std::vector<std::vector<int>>& ConstraintToVar() const
143  ABSL_SHARED_LOCKS_REQUIRED(graph_mutex_) {
144  return constraint_to_var_;
145  }
146  const std::vector<std::vector<int>>& VarToConstraint() const
147  ABSL_SHARED_LOCKS_REQUIRED(graph_mutex_) {
148  return var_to_constraint_;
149  }
150 
151  // Returns all the constraints indices of a given type.
152  const absl::Span<const int> TypeToConstraints(
153  ConstraintProto::ConstraintCase type) const {
154  if (type >= type_to_constraints_.size()) return {};
155  return absl::MakeSpan(type_to_constraints_[type]);
156  }
157 
158  // Returns the list of indices of active interval constraints according
159  // to the initial_solution and the parameter lns_focus_on_performed_intervals.
160  // If true, this method returns the list of performed intervals in the
161  // solution. If false, it returns all intervals of the model.
162  std::vector<int> GetActiveIntervals(
163  const CpSolverResponse& initial_solution) const;
164 
165  // The initial problem.
166  // Note that the domain of the variables are not updated here.
167  const CpModelProto& ModelProto() const { return model_proto_; }
168  const SatParameters& Parameters() const { return parameters_; }
169 
171  return *shared_response_;
172  }
173 
174  // TODO(user): Refactor the class to be thread-safe instead, it should be
175  // safer and more easily maintenable. Some complication with accessing the
176  // variable<->constraint graph efficiently though.
177 
178  // Note: This mutex needs to be public for thread annotations.
179  mutable absl::Mutex graph_mutex_;
180 
181  private:
182  // Recompute most of the class member. This needs to be called when the
183  // domains of the variables are updated.
184  void RecomputeHelperData();
185 
186  // Indicates if a variable is fixed in the model.
187  bool IsConstant(int var) const ABSL_SHARED_LOCKS_REQUIRED(domain_mutex_);
188 
189  const SatParameters& parameters_;
190  const CpModelProto& model_proto_;
191  int shared_bounds_id_;
192  SharedTimeLimit* shared_time_limit_;
193  SharedBoundsManager* shared_bounds_;
194  SharedResponseManager* shared_response_;
195  SharedRelaxationSolutionRepository* shared_relaxation_solutions_;
196 
197  // This proto will only contain the field variables() with an updated version
198  // of the domains compared to model_proto_.variables(). We do it like this to
199  // reduce the memory footprint of the helper when the model is large.
200  //
201  // TODO(user): Use custom domain repository rather than a proto?
202  CpModelProto model_proto_with_only_variables_ ABSL_GUARDED_BY(domain_mutex_);
203 
204  // Constraints by types.
205  std::vector<std::vector<int>> type_to_constraints_;
206 
207  // Variable-Constraint graph.
208  std::vector<std::vector<int>> constraint_to_var_
209  ABSL_GUARDED_BY(graph_mutex_);
210  std::vector<std::vector<int>> var_to_constraint_
211  ABSL_GUARDED_BY(graph_mutex_);
212 
213  // The set of active variables, that is the list of non constant variables if
214  // parameters_.focus_on_decision_variables() is false, or the list of non
215  // constant decision variables otherwise. It is stored both as a list and as a
216  // set (using a Boolean vector).
217  std::vector<bool> active_variables_set_ ABSL_GUARDED_BY(graph_mutex_);
218  std::vector<int> active_variables_ ABSL_GUARDED_BY(graph_mutex_);
219 
220  mutable absl::Mutex domain_mutex_;
221 };
222 
223 // Base class for a CpModelProto neighborhood generator.
225  public:
226  NeighborhoodGenerator(const std::string& name,
227  NeighborhoodGeneratorHelper const* helper)
228  : name_(name), helper_(*helper), difficulty_(0.5) {}
230 
231  // Generates a "local" subproblem for the given seed.
232  //
233  // The difficulty will be in [0, 1] and is related to the asked neighborhood
234  // size (and thus local problem difficulty). A difficulty of 0.0 means empty
235  // neighborhood and a difficulty of 1.0 means the full problem. The algorithm
236  // should try to generate a neighborhood according to this difficulty which
237  // will be dynamically adjusted depending on whether or not we can solve the
238  // subproblem in a given time limit.
239  //
240  // The given initial_solution should contain a feasible solution to the
241  // initial CpModelProto given to this class. Any solution to the returned
242  // CPModelProto should also be valid solution to the same initial model.
243  //
244  // This function should be thread-safe.
245  virtual Neighborhood Generate(const CpSolverResponse& initial_solution,
246  double difficulty, absl::BitGenRef random) = 0;
247 
248  // Returns true if the neighborhood generator can generate a neighborhood.
249  virtual bool ReadyToGenerate() const;
250 
251  // Returns true if the neighborhood generator generates relaxation of the
252  // given problem.
253  virtual bool IsRelaxationGenerator() const { return false; }
254 
255  // Uses UCB1 algorithm to compute the score (Multi armed bandit problem).
256  // Details are at
257  // https://lilianweng.github.io/lil-log/2018/01/23/the-multi-armed-bandit-problem-and-its-solutions.html.
258  // 'total_num_calls' should be the sum of calls across all generators part of
259  // the multi armed bandit problem.
260  // If the generator is called less than 10 times then the method returns
261  // infinity as score in order to get more data about the generator
262  // performance.
263  double GetUCBScore(int64_t total_num_calls) const;
264 
265  // Adds solve data about one "solved" neighborhood.
266  struct SolveData {
267  // Neighborhood Id. Used to identify the neighborhood by a generator.
268  // Currently only used by WeightedRandomRelaxationNeighborhoodGenerator.
269  int64_t neighborhood_id = 0;
270 
271  // The status of the sub-solve.
273 
274  // The difficulty when this neighborhood was generated.
275  double difficulty = 0.0;
276 
277  // The determinitic time limit given to the solver for this neighborhood.
278  double deterministic_limit = 0.0;
279 
280  // The time it took to solve this neighborhood.
281  double deterministic_time = 0.0;
282 
283  // Objective information. These only refer to the "internal" objective
284  // without scaling or offset so we are exact and it is always in the
285  // minimization direction.
286  // - The initial best objective is the one of the best known solution at the
287  // time the neighborhood was generated.
288  // - The base objective is the one of the base solution from which this
289  // neighborhood was generated.
290  // - The new objective is the objective of the best solution found by
291  // solving the neighborhood.
292  IntegerValue initial_best_objective = IntegerValue(0);
293  IntegerValue base_objective = IntegerValue(0);
294  IntegerValue new_objective = IntegerValue(0);
295 
296  // Bounds data is only used by relaxation neighborhoods.
297  IntegerValue initial_best_objective_bound = IntegerValue(0);
298  IntegerValue new_objective_bound = IntegerValue(0);
299 
300  // This is just used to construct a deterministic order for the updates.
301  bool operator<(const SolveData& o) const {
302  return std::tie(status, difficulty, deterministic_limit,
306  neighborhood_id) <
307  std::tie(o.status, o.difficulty, o.deterministic_limit,
311  o.neighborhood_id);
312  }
313  };
314  void AddSolveData(SolveData data) {
315  absl::MutexLock mutex_lock(&generator_mutex_);
316  solve_data_.push_back(data);
317  }
318 
319  // Process all the recently added solve data and update this generator
320  // score and difficulty.
321  void Synchronize();
322 
323  // Returns a short description of the generator.
324  std::string name() const { return name_; }
325 
326  // Number of times this generator was called.
327  int64_t num_calls() const {
328  absl::MutexLock mutex_lock(&generator_mutex_);
329  return num_calls_;
330  }
331 
332  // Number of time the neighborhood was fully solved (OPTIMAL/INFEASIBLE).
333  int64_t num_fully_solved_calls() const {
334  absl::MutexLock mutex_lock(&generator_mutex_);
335  return num_fully_solved_calls_;
336  }
337 
338  // The current difficulty of this generator
339  double difficulty() const {
340  absl::MutexLock mutex_lock(&generator_mutex_);
341  return difficulty_.value();
342  }
343 
344  // The current time limit that the sub-solve should use on this generator.
345  double deterministic_limit() const {
346  absl::MutexLock mutex_lock(&generator_mutex_);
347  return deterministic_limit_;
348  }
349 
350  // The sum of the deterministic time spent in this generator.
351  double deterministic_time() const {
352  absl::MutexLock mutex_lock(&generator_mutex_);
353  return deterministic_time_;
354  }
355 
356  protected:
357  // Triggered with each call to Synchronize() for each recently added
358  // SolveData. This is meant to be used for processing feedbacks by specific
359  // neighborhood generators to adjust the neighborhood generation process.
360  virtual void AdditionalProcessingOnSynchronize(const SolveData& solve_data) {}
361 
362  const std::string name_;
364  mutable absl::Mutex generator_mutex_;
365 
366  private:
367  std::vector<SolveData> solve_data_;
368 
369  // Current parameters to be used when generating/solving a neighborhood with
370  // this generator. Only updated on Synchronize().
371  AdaptiveParameterValue difficulty_;
372  double deterministic_limit_ = 0.1;
373 
374  // Current statistics of the last solved neighborhood.
375  // Only updated on Synchronize().
376  int64_t num_calls_ = 0;
377  int64_t num_fully_solved_calls_ = 0;
378  int64_t num_consecutive_non_improving_calls_ = 0;
379  double deterministic_time_ = 0.0;
380  double current_average_ = 0.0;
381 };
382 
383 // Pick a random subset of variables.
385  public:
387  NeighborhoodGeneratorHelper const* helper, const std::string& name)
388  : NeighborhoodGenerator(name, helper) {}
389  Neighborhood Generate(const CpSolverResponse& initial_solution,
390  double difficulty, absl::BitGenRef random) final;
391 };
392 
393 // Pick a random subset of constraints and relax all the variables of these
394 // constraints. Note that to satisfy the difficulty, we might not relax all the
395 // variable of the "last" constraint.
397  public:
399  NeighborhoodGeneratorHelper const* helper, const std::string& name)
400  : NeighborhoodGenerator(name, helper) {}
401  Neighborhood Generate(const CpSolverResponse& initial_solution,
402  double difficulty, absl::BitGenRef random) final;
403 };
404 
405 // Pick a random subset of variables that are constructed by a BFS in the
406 // variable <-> constraint graph. That is, pick a random variable, then all the
407 // variable connected by some constraint to the first one, and so on. The
408 // variable of the last "level" are selected randomly.
410  public:
412  NeighborhoodGeneratorHelper const* helper, const std::string& name)
413  : NeighborhoodGenerator(name, helper) {}
414  Neighborhood Generate(const CpSolverResponse& initial_solution,
415  double difficulty, absl::BitGenRef random) final;
416 };
417 
418 // Pick a random subset of constraint and relax all of their variables. We are a
419 // bit smarter than this because after the first constraint is selected, we only
420 // select constraints that share at least one variable with the already selected
421 // constraints. The variable from the "last" constraint are selected randomly.
423  public:
425  NeighborhoodGeneratorHelper const* helper, const std::string& name)
426  : NeighborhoodGenerator(name, helper) {}
427  Neighborhood Generate(const CpSolverResponse& initial_solution,
428  double difficulty, absl::BitGenRef random) final;
429 };
430 
431 // Helper method for the scheduling neighborhood generators. Returns the model
432 // as neighborhood for the given set of intervals to relax. For each no_overlap
433 // constraints, it adds strict relation order between the non-relaxed intervals.
435  const absl::Span<const int> intervals_to_relax,
436  const CpSolverResponse& initial_solution,
437  const NeighborhoodGeneratorHelper& helper);
438 
439 // Only make sense for scheduling problem. This select a random set of interval
440 // of the problem according to the difficulty. Then, for each no_overlap
441 // constraints, it adds strict relation order between the non-relaxed intervals.
442 //
443 // TODO(user): Also deal with cumulative constraint.
445  public:
447  NeighborhoodGeneratorHelper const* helper, const std::string& name)
448  : NeighborhoodGenerator(name, helper) {}
449 
450  Neighborhood Generate(const CpSolverResponse& initial_solution,
451  double difficulty, absl::BitGenRef random) final;
452 };
453 
454 // Similar to SchedulingNeighborhoodGenerator except the set of intervals that
455 // are relaxed are from a specific random time interval.
457  public:
459  NeighborhoodGeneratorHelper const* helper, const std::string& name)
460  : NeighborhoodGenerator(name, helper) {}
461 
462  Neighborhood Generate(const CpSolverResponse& initial_solution,
463  double difficulty, absl::BitGenRef random) final;
464 };
465 
466 // Generates a neighborhood by fixing the variables to solutions reported in
467 // various repositories. This is inspired from RINS published in "Exploring
468 // relaxation induced neighborhoods to improve MIP solutions" 2004 by E. Danna
469 // et.
470 //
471 // If incomplete_solutions is provided, this generates a neighborhood by fixing
472 // the variable values to a solution in the SharedIncompleteSolutionManager and
473 // ignores the other repositories.
474 //
475 // Otherwise, if response_manager is not provided, this generates a neighborhood
476 // using only the linear/general relaxation values. The domain of the variables
477 // are reduced to the integer values around their lp solution/relaxation
478 // solution values. This was published in "RENS – The Relaxation Enforced
479 // Neighborhood" 2009 by Timo Berthold.
481  public:
483  NeighborhoodGeneratorHelper const* helper,
484  const SharedResponseManager* response_manager,
488  const std::string& name)
489  : NeighborhoodGenerator(name, helper),
490  response_manager_(response_manager),
491  relaxation_solutions_(relaxation_solutions),
492  lp_solutions_(lp_solutions),
493  incomplete_solutions_(incomplete_solutions) {
494  CHECK(lp_solutions_ != nullptr || relaxation_solutions_ != nullptr ||
495  incomplete_solutions != nullptr);
496  }
497 
498  // Both initial solution and difficulty values are ignored.
499  Neighborhood Generate(const CpSolverResponse& initial_solution,
500  double difficulty, absl::BitGenRef random) final;
501 
502  // Returns true if the required solutions are available.
503  bool ReadyToGenerate() const override;
504 
505  private:
506  const SharedResponseManager* response_manager_;
507  const SharedRelaxationSolutionRepository* relaxation_solutions_;
508  const SharedLPSolutionRepository* lp_solutions_;
509  SharedIncompleteSolutionManager* incomplete_solutions_;
510 };
511 
512 // Generates a relaxation of the original model by removing a consecutive span
513 // of constraints starting at a random index. The number of constraints removed
514 // is in sync with the difficulty passed to the generator.
516  : public NeighborhoodGenerator {
517  public:
519  NeighborhoodGeneratorHelper const* helper, const std::string& name)
520  : NeighborhoodGenerator(name, helper) {}
521  Neighborhood Generate(const CpSolverResponse& initial_solution,
522  double difficulty, absl::BitGenRef random) final;
523 
524  bool IsRelaxationGenerator() const override { return true; }
525  bool ReadyToGenerate() const override { return true; }
526 };
527 
528 // Generates a relaxation of the original model by removing some constraints
529 // randomly with a given weight for each constraint that controls the
530 // probability of constraint getting removed. The number of constraints removed
531 // is in sync with the difficulty passed to the generator. Higher weighted
532 // constraints are more likely to get removed.
534  : public NeighborhoodGenerator {
535  public:
537  NeighborhoodGeneratorHelper const* helper, const std::string& name);
538 
539  // Generates the neighborhood as described above. Also stores the removed
540  // constraints indices for adjusting the weights.
541  Neighborhood Generate(const CpSolverResponse& initial_solution,
542  double difficulty, absl::BitGenRef random) final;
543 
544  bool IsRelaxationGenerator() const override { return true; }
545  bool ReadyToGenerate() const override { return true; }
546 
547  private:
548  // Adjusts the weights of the constraints removed to get the neighborhood
549  // based on the solve_data.
550  void AdditionalProcessingOnSynchronize(const SolveData& solve_data) override
551  ABSL_EXCLUSIVE_LOCKS_REQUIRED(generator_mutex_);
552 
553  // Higher weighted constraints are more likely to get removed.
554  std::vector<double> constraint_weights_;
555  int num_removable_constraints_ = 0;
556 
557  // Indices of the removed constraints per generated neighborhood.
558  absl::flat_hash_map<int64_t, std::vector<int>> removed_constraints_
559  ABSL_GUARDED_BY(generator_mutex_);
560 
561  // TODO(user): Move this to parent class if other generators start using
562  // feedbacks.
563  int64_t next_available_id_ ABSL_GUARDED_BY(generator_mutex_) = 0;
564 };
565 
566 } // namespace sat
567 } // namespace operations_research
568 
569 #endif // OR_TOOLS_SAT_CP_MODEL_LNS_H_
#define CHECK(condition)
Definition: base/logging.h:498
ConsecutiveConstraintsRelaxationNeighborhoodGenerator(NeighborhoodGeneratorHelper const *helper, const std::string &name)
Definition: cp_model_lns.h:518
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:424
const std::vector< std::vector< int > > & VarToConstraint() const ABSL_SHARED_LOCKS_REQUIRED(graph_mutex_)
Definition: cp_model_lns.h:146
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:34
const SharedResponseManager & shared_response() const
Definition: cp_model_lns.h:170
Neighborhood FixAllVariables(const CpSolverResponse &initial_solution) const
std::function< void()> GenerateTask(int64_t task_id) override
Definition: cp_model_lns.h:77
Neighborhood FixGivenVariables(const CpSolverResponse &initial_solution, const std::vector< int > &variables_to_fix) const
const absl::Span< const int > TypeToConstraints(ConstraintProto::ConstraintCase type) const
Definition: cp_model_lns.h:152
bool CopyAndFixVariables(const CpModelProto &source_model, const absl::flat_hash_set< int > &fixed_variables_set, const CpSolverResponse &initial_solution, CpModelProto *output_model) const
Neighborhood RelaxGivenVariables(const CpSolverResponse &initial_solution, const std::vector< int > &relaxed_variables) const
std::vector< int > GetActiveIntervals(const CpSolverResponse &initial_solution) const
const std::vector< std::vector< int > > & ConstraintToVar() const ABSL_SHARED_LOCKS_REQUIRED(graph_mutex_)
Definition: cp_model_lns.h:142
bool IsActive(int var) const ABSL_SHARED_LOCKS_REQUIRED(graph_mutex_)
Neighborhood RemoveMarkedConstraints(const std::vector< int > &constraints_to_remove) const
void AddSolutionHinting(const CpSolverResponse &initial_solution, CpModelProto *model_proto) 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:226
virtual void AdditionalProcessingOnSynchronize(const SolveData &solve_data)
Definition: cp_model_lns.h:360
const NeighborhoodGeneratorHelper & helper_
Definition: cp_model_lns.h:363
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:482
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:446
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:458
Neighborhood Generate(const CpSolverResponse &initial_solution, double difficulty, absl::BitGenRef random) final
SimpleConstraintNeighborhoodGenerator(NeighborhoodGeneratorHelper const *helper, const std::string &name)
Definition: cp_model_lns.h:398
Neighborhood Generate(const CpSolverResponse &initial_solution, double difficulty, absl::BitGenRef random) final
Neighborhood Generate(const CpSolverResponse &initial_solution, double difficulty, absl::BitGenRef random) final
SimpleNeighborhoodGenerator(NeighborhoodGeneratorHelper const *helper, const std::string &name)
Definition: cp_model_lns.h:386
VariableGraphNeighborhoodGenerator(NeighborhoodGeneratorHelper const *helper, const std::string &name)
Definition: cp_model_lns.h:411
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