14 #ifndef OR_TOOLS_SAT_CP_MODEL_LNS_H_
15 #define OR_TOOLS_SAT_CP_MODEL_LNS_H_
25 #include "absl/base/thread_annotations.h"
26 #include "absl/container/flat_hash_map.h"
27 #include "absl/container/flat_hash_set.h"
28 #include "absl/random/bit_gen_ref.h"
29 #include "absl/synchronization/mutex.h"
30 #include "absl/time/time.h"
31 #include "absl/types/span.h"
34 #include "ortools/sat/cp_model.pb.h"
38 #include "ortools/sat/sat_parameters.pb.h"
117 const CpSolverResponse& base_solution,
118 const absl::flat_hash_set<int>& variables_to_fix)
const;
122 const std::vector<int>& constraints_to_remove)
const;
127 const CpSolverResponse& initial_solution,
128 const std::vector<int>& relaxed_variables)
const;
153 std::vector<int> result;
155 result = active_variables_;
161 return active_variables_.size();
165 std::vector<int> result;
167 result = active_objective_variables_;
173 const int target_size = std::ceil(difficulty * active_variables_.size());
174 return target_size == active_variables_.size();
181 return active_variables_;
188 return constraint_to_var_;
192 return var_to_constraint_;
197 ConstraintProto::ConstraintCase
type)
const {
198 if (
type >= type_to_constraints_.size())
return {};
199 return absl::MakeSpan(type_to_constraints_[
type]);
207 const CpSolverResponse& initial_solution)
const;
219 const CpSolverResponse& initial_solution)
const;
225 const absl::flat_hash_set<int>& ignored_intervals,
226 const CpSolverResponse& initial_solution, absl::BitGenRef random)
const;
230 const CpModelProto&
ModelProto()
const {
return model_proto_; }
231 const SatParameters&
Parameters()
const {
return parameters_; }
234 return *shared_response_;
251 void InitializeHelperData();
255 void RecomputeHelperData();
258 bool IsConstant(
int var)
const ABSL_SHARED_LOCKS_REQUIRED(domain_mutex_);
262 bool ObjectiveDomainIsConstraining() const
263 ABSL_SHARED_LOCKS_REQUIRED(domain_mutex_);
265 const SatParameters& parameters_;
266 const CpModelProto& model_proto_;
267 int shared_bounds_id_;
276 CpModelProto model_proto_with_only_variables_ ABSL_GUARDED_BY(domain_mutex_);
279 std::vector<std::vector<
int>> type_to_constraints_;
283 std::vector<
bool> is_in_objective_;
288 CpModelProto simplied_model_proto_ ABSL_GUARDED_BY(
graph_mutex_);
295 std::vector<std::vector<
int>> constraint_to_var_
297 std::vector<std::vector<
int>> var_to_constraint_
303 std::vector<std::vector<
int>> components_ ABSL_GUARDED_BY(
graph_mutex_);
304 std::vector<
int> var_to_component_index_ ABSL_GUARDED_BY(
graph_mutex_);
309 std::vector<
bool> active_variables_set_ ABSL_GUARDED_BY(
graph_mutex_);
310 std::vector<
int> active_variables_ ABSL_GUARDED_BY(
graph_mutex_);
313 std::vector<
int> active_objective_variables_ ABSL_GUARDED_BY(
graph_mutex_);
315 mutable
absl::Mutex domain_mutex_;
318 absl::Time last_logging_time_;
326 :
name_(
name), helper_(*helper), difficulty_(0.5) {}
344 double difficulty, absl::BitGenRef random) = 0;
347 virtual bool ReadyToGenerate()
const;
357 double GetUCBScore(int64_t total_num_calls)
const;
362 CpSolverStatus
status = CpSolverStatus::UNKNOWN;
365 double difficulty = 0.0;
368 double deterministic_limit = 0.0;
382 IntegerValue initial_best_objective = IntegerValue(0);
383 IntegerValue base_objective = IntegerValue(0);
384 IntegerValue new_objective = IntegerValue(0);
388 return std::tie(
status, difficulty, deterministic_limit,
390 base_objective, new_objective) <
397 absl::MutexLock mutex_lock(&generator_mutex_);
398 solve_data_.push_back(data);
410 absl::MutexLock mutex_lock(&generator_mutex_);
416 absl::MutexLock mutex_lock(&generator_mutex_);
417 return num_fully_solved_calls_;
422 absl::MutexLock mutex_lock(&generator_mutex_);
423 return difficulty_.value();
428 absl::MutexLock mutex_lock(&generator_mutex_);
429 return deterministic_limit_;
434 absl::MutexLock mutex_lock(&generator_mutex_);
444 std::vector<SolveData> solve_data_;
449 double deterministic_limit_ = 0.1;
453 int64_t num_calls_ = 0;
454 int64_t num_fully_solved_calls_ = 0;
455 int64_t num_consecutive_non_improving_calls_ = 0;
457 double current_average_ = 0.0;
469 Neighborhood Generate(
const CpSolverResponse& initial_solution,
470 double difficulty, absl::BitGenRef random)
final;
484 Neighborhood Generate(
const CpSolverResponse& initial_solution,
485 double difficulty, absl::BitGenRef random)
final;
500 Neighborhood Generate(
const CpSolverResponse& initial_solution,
501 double difficulty, absl::BitGenRef random)
final;
513 Neighborhood Generate(
const CpSolverResponse& initial_solution,
514 double difficulty, absl::BitGenRef random)
final;
523 Neighborhood Generate(
const CpSolverResponse& initial_solution,
524 double difficulty, absl::BitGenRef random)
final;
532 const absl::Span<const int> intervals_to_relax,
533 const CpSolverResponse& initial_solution, absl::BitGenRef random,
540 const absl::Span<
const std::pair<int, int>> precedences,
541 const CpSolverResponse& initial_solution,
554 Neighborhood Generate(
const CpSolverResponse& initial_solution,
555 double difficulty, absl::BitGenRef random)
final;
570 Neighborhood Generate(
const CpSolverResponse& initial_solution,
571 double difficulty, absl::BitGenRef random)
final;
582 Neighborhood Generate(
const CpSolverResponse& initial_solution,
583 double difficulty, absl::BitGenRef random)
final;
594 const std::vector<std::vector<int>>& intervals_in_constraints,
595 const std::string&
name)
597 intervals_in_constraints_(intervals_in_constraints) {}
599 Neighborhood Generate(
const CpSolverResponse& initial_solution,
600 double difficulty, absl::BitGenRef random)
final;
603 const std::vector<std::vector<int>> intervals_in_constraints_;
604 absl::flat_hash_set<int> intervals_to_relax_;
612 const std::string&
name)
615 Neighborhood Generate(
const CpSolverResponse& initial_solution,
616 double difficulty, absl::BitGenRef random)
final;
624 const std::string&
name)
627 Neighborhood Generate(
const CpSolverResponse& initial_solution,
628 double difficulty, absl::BitGenRef random)
final;
644 Neighborhood Generate(
const CpSolverResponse& initial_solution,
645 double difficulty, absl::BitGenRef random)
final;
670 const std::string&
name)
672 response_manager_(response_manager),
676 CHECK(lp_solutions_ !=
nullptr || relaxation_solutions_ !=
nullptr ||
681 Neighborhood Generate(
const CpSolverResponse& initial_solution,
682 double difficulty, absl::BitGenRef random)
final;
685 bool ReadyToGenerate()
const override;
ConstraintGraphNeighborhoodGenerator(NeighborhoodGeneratorHelper const *helper, const std::string &name)
const std::vector< std::vector< int > > & VarToConstraint() const ABSL_SHARED_LOCKS_REQUIRED(graph_mutex_)
const SharedResponseManager & shared_response() const
std::vector< std::pair< int, int > > GetSchedulingPrecedences(const absl::flat_hash_set< int > &ignored_intervals, const CpSolverResponse &initial_solution, absl::BitGenRef random) const
Neighborhood FullNeighborhood() const
std::vector< int > ActiveVariables() const
Neighborhood FixAllVariables(const CpSolverResponse &initial_solution) const
int NumActiveVariables() const
std::function< void()> GenerateTask(int64_t) override
Neighborhood FixGivenVariables(const CpSolverResponse &base_solution, const absl::flat_hash_set< int > &variables_to_fix) const
const absl::Span< const int > TypeToConstraints(ConstraintProto::ConstraintCase type) const
bool DifficultyMeansFullNeighborhood(double difficulty) const
Neighborhood NoNeighborhood() const
Neighborhood RelaxGivenVariables(const CpSolverResponse &initial_solution, const std::vector< int > &relaxed_variables) const
std::vector< int > GetActiveIntervals(const CpSolverResponse &initial_solution) const
std::vector< int > ActiveObjectiveVariables() const
const CpModelProto & ModelProto() const
const std::vector< std::vector< int > > & ConstraintToVar() const ABSL_SHARED_LOCKS_REQUIRED(graph_mutex_)
std::vector< std::vector< int > > GetUniqueIntervalSets() const
bool TaskIsAvailable() override
NeighborhoodGeneratorHelper(CpModelProto const *model_proto, SatParameters const *parameters, SharedResponseManager *shared_response, SharedBoundsManager *shared_bounds=nullptr)
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
const std::vector< int > & ActiveVariablesWhileHoldingLock() const ABSL_SHARED_LOCKS_REQUIRED(graph_mutex_)
const SatParameters & Parameters() const
void Synchronize() override
std::vector< std::vector< int > > GetRoutingPaths(const CpSolverResponse &initial_solution) const
virtual Neighborhood Generate(const CpSolverResponse &initial_solution, double difficulty, absl::BitGenRef random)=0
absl::Mutex generator_mutex_
virtual ~NeighborhoodGenerator()
void AddSolveData(SolveData data)
double difficulty() const
NeighborhoodGenerator(const std::string &name, NeighborhoodGeneratorHelper const *helper)
int64_t num_fully_solved_calls() const
int64_t num_calls() const
const NeighborhoodGeneratorHelper & helper_
double deterministic_time() const
double deterministic_limit() const
RandomIntervalSchedulingNeighborhoodGenerator(NeighborhoodGeneratorHelper const *helper, const std::string &name)
RandomPrecedenceSchedulingNeighborhoodGenerator(NeighborhoodGeneratorHelper const *helper, const std::string &name)
RelaxObjectiveVariablesGenerator(NeighborhoodGeneratorHelper const *helper, const std::string &name)
RelaxRandomConstraintsGenerator(NeighborhoodGeneratorHelper const *helper, const std::string &name)
RelaxRandomVariablesGenerator(NeighborhoodGeneratorHelper const *helper, const std::string &name)
RelaxationInducedNeighborhoodGenerator(NeighborhoodGeneratorHelper const *helper, const SharedResponseManager *response_manager, const SharedRelaxationSolutionRepository *relaxation_solutions, const SharedLPSolutionRepository *lp_solutions, SharedIncompleteSolutionManager *incomplete_solutions, const std::string &name)
RoutingFullPathNeighborhoodGenerator(NeighborhoodGeneratorHelper const *helper, const std::string &name)
RoutingPathNeighborhoodGenerator(NeighborhoodGeneratorHelper const *helper, const std::string &name)
RoutingRandomNeighborhoodGenerator(NeighborhoodGeneratorHelper const *helper, const std::string &name)
SchedulingResourceWindowsNeighborhoodGenerator(NeighborhoodGeneratorHelper const *helper, const std::vector< std::vector< int >> &intervals_in_constraints, const std::string &name)
SchedulingTimeWindowNeighborhoodGenerator(NeighborhoodGeneratorHelper const *helper, const std::string &name)
SubsolverType type() const
double deterministic_time_
double deterministic_time() const
VariableGraphNeighborhoodGenerator(NeighborhoodGeneratorHelper const *helper, const std::string &name)
SharedRelaxationSolutionRepository * relaxation_solutions
SharedLPSolutionRepository * lp_solutions
CpModelProto const * model_proto
SharedIncompleteSolutionManager * incomplete_solutions
Neighborhood GenerateSchedulingNeighborhoodFromRelaxedIntervals(const absl::Span< const int > intervals_to_relax, const CpSolverResponse &initial_solution, absl::BitGenRef random, const NeighborhoodGeneratorHelper &helper)
Neighborhood GenerateSchedulingNeighborhoodFromIntervalPrecedences(const absl::Span< const std::pair< int, int >> precedences, const CpSolverResponse &initial_solution, const NeighborhoodGeneratorHelper &helper)
Collection of objects used to extend the Constraint Solver library.
bool operator<(const SolveData &o) const
IntegerValue base_objective
IntegerValue initial_best_objective
double deterministic_limit
IntegerValue new_objective
double deterministic_time
int num_relaxed_variables
std::vector< int > variables_that_can_be_fixed_to_local_optimum
int num_relaxed_variables_in_objective
std::vector< int > constraints_to_ignore