14#ifndef OR_TOOLS_SAT_SYNCHRONIZATION_H_
15#define OR_TOOLS_SAT_SYNCHRONIZATION_H_
23#include "absl/random/bit_gen_ref.h"
24#include "absl/random/random.h"
25#include "absl/synchronization/mutex.h"
46template <
typename ValueType>
102 void Add(
const Solution& solution);
115 ABSL_EXCLUSIVE_LOCKS_REQUIRED(
mutex_);
164 std::vector<std::vector<double>> solutions_;
165 mutable absl::Mutex mutex_;
265 IntegerValue lb, IntegerValue ub);
320 dump_prefix_ = dump_prefix;
331 absl::MutexLock mutex_lock(&mutex_);
332 return &best_response_;
336 void TestGapLimitsIfNeeded() ABSL_EXCLUSIVE_LOCKS_REQUIRED(mutex_);
337 void FillObjectiveValuesInBestResponse()
338 ABSL_EXCLUSIVE_LOCKS_REQUIRED(mutex_);
340 ABSL_EXCLUSIVE_LOCKS_REQUIRED(mutex_);
341 void UpdatePrimalIntegralInternal() ABSL_EXCLUSIVE_LOCKS_REQUIRED(mutex_);
343 void RegisterSolutionFound(const
std::
string& improvement_info)
344 ABSL_EXCLUSIVE_LOCKS_REQUIRED(mutex_);
345 void RegisterObjectiveBoundImprovement(const
std::
string& improvement_info)
346 ABSL_EXCLUSIVE_LOCKS_REQUIRED(mutex_);
348 const
bool enumerate_all_solutions_;
353 mutable
absl::Mutex mutex_;
356 double absolute_gap_limit_ ABSL_GUARDED_BY(mutex_) = 0.0;
357 double relative_gap_limit_ ABSL_GUARDED_BY(mutex_) = 0.0;
362 int num_solutions_ ABSL_GUARDED_BY(mutex_) = 0;
363 int64_t inner_objective_lower_bound_ ABSL_GUARDED_BY(mutex_) =
364 std::numeric_limits<int64_t>::
min();
365 int64_t inner_objective_upper_bound_ ABSL_GUARDED_BY(mutex_) =
366 std::numeric_limits<int64_t>::
max();
367 int64_t best_solution_objective_value_ ABSL_GUARDED_BY(mutex_) =
368 std::numeric_limits<int64_t>::
max();
370 IntegerValue synchronized_inner_objective_lower_bound_ ABSL_GUARDED_BY(
371 mutex_) = IntegerValue(
std::numeric_limits<int64_t>::
min());
372 IntegerValue synchronized_inner_objective_upper_bound_ ABSL_GUARDED_BY(
373 mutex_) = IntegerValue(
std::numeric_limits<int64_t>::
max());
375 bool update_integral_on_each_change_ ABSL_GUARDED_BY(mutex_) = false;
376 double primal_integral_ ABSL_GUARDED_BY(mutex_) = 0.0;
377 double last_absolute_gap_ ABSL_GUARDED_BY(mutex_) = 0.0;
378 double last_primal_integral_time_stamp_ ABSL_GUARDED_BY(mutex_) = 0.0;
380 int next_callback_id_ ABSL_GUARDED_BY(mutex_) = 0;
382 callbacks_ ABSL_GUARDED_BY(mutex_);
385 ABSL_GUARDED_BY(mutex_);
387 ABSL_GUARDED_BY(mutex_);
390 std::
string dump_prefix_;
393 std::map<
std::
string,
int> primal_improvements_count_ ABSL_GUARDED_BY(mutex_);
394 std::map<
std::
string,
int> dual_improvements_count_ ABSL_GUARDED_BY(mutex_);
409 const std::string& worker_name,
410 const std::vector<int>& variables,
411 const std::vector<int64_t>& new_lower_bounds,
412 const std::vector<int64_t>& new_upper_bounds);
421 void GetChangedBounds(
int id, std::vector<int>* variables,
422 std::vector<int64_t>* new_lower_bounds,
423 std::vector<int64_t>* new_upper_bounds);
430 const int num_variables_;
436 std::vector<int64_t> lower_bounds_ ABSL_GUARDED_BY(mutex_);
437 std::vector<int64_t> upper_bounds_ ABSL_GUARDED_BY(mutex_);
439 ABSL_GUARDED_BY(mutex_);
442 std::vector<int64_t> synchronized_lower_bounds_ ABSL_GUARDED_BY(mutex_);
443 std::vector<int64_t> synchronized_upper_bounds_ ABSL_GUARDED_BY(mutex_);
444 std::deque<SparseBitset<int64_t>> id_to_changed_variables_
445 ABSL_GUARDED_BY(mutex_);
448template <
typename ValueType>
450 absl::MutexLock mutex_lock(&mutex_);
451 return solutions_.size();
454template <
typename ValueType>
457 absl::MutexLock mutex_lock(&mutex_);
458 return solutions_[i];
461template <
typename ValueType>
463 int var_index,
int solution_index)
const {
464 absl::MutexLock mutex_lock(&mutex_);
465 return solutions_[solution_index].variable_values[var_index];
469template <
typename ValueType>
472 absl::BitGenRef random)
const {
473 absl::MutexLock mutex_lock(&mutex_);
474 const int64_t best_rank = solutions_[0].rank;
483 const int kExplorationThreshold = 100;
486 tmp_indices_.clear();
487 for (
int i = 0; i < solutions_.size(); ++i) {
488 const auto& solution = solutions_[i];
489 if (solution.rank == best_rank &&
490 solution.num_selected <= kExplorationThreshold) {
491 tmp_indices_.push_back(i);
496 if (tmp_indices_.empty()) {
497 index = absl::Uniform<int>(random, 0, solutions_.size());
499 index = tmp_indices_[absl::Uniform<int>(random, 0, tmp_indices_.size())];
501 solutions_[
index].num_selected++;
502 return solutions_[
index];
505template <
typename ValueType>
507 absl::MutexLock mutex_lock(&mutex_);
508 AddInternal(solution);
511template <
typename ValueType>
514 int worse_solution_index = 0;
515 for (
int i = 0; i < new_solutions_.size(); ++i) {
517 if (new_solutions_[i] == solution)
return;
518 if (new_solutions_[worse_solution_index] < new_solutions_[i]) {
519 worse_solution_index = i;
522 if (new_solutions_.size() < num_solutions_to_keep_) {
523 new_solutions_.push_back(solution);
524 }
else if (solution < new_solutions_[worse_solution_index]) {
525 new_solutions_[worse_solution_index] = solution;
529template <
typename ValueType>
531 absl::MutexLock mutex_lock(&mutex_);
532 solutions_.insert(solutions_.end(), new_solutions_.begin(),
533 new_solutions_.end());
534 new_solutions_.clear();
541 if (solutions_.size() > num_solutions_to_keep_) {
542 solutions_.resize(num_solutions_to_keep_);
544 num_synchronization_++;
#define CHECK_GE(val1, val2)
Class that owns everything related to a particular optimization model.
void AddNewSolution(const std::vector< double > &lp_solution)
std::vector< double > GetNewSolution()
bool HasNewSolution() const
SharedLPSolutionRepository(int num_solutions_to_keep)
void NewLPSolution(std::vector< double > lp_solution)
SharedRelaxationSolutionRepository(int num_solutions_to_keep)
void NewRelaxationSolution(const CpSolverResponse &response)
bool ProblemIsSolved() const
void InitializeObjective(const CpModelProto &cp_model)
void SetStatsFromModel(Model *model)
CpSolverResponse GetResponse(bool full_response=true)
double PrimalIntegral() const
SharedSolutionRepository< int64_t > * MutableSolutionsRepository()
void AddFinalSolutionPostprocessor(std::function< void(CpSolverResponse *)> postprocessor)
void set_dump_prefix(const std::string &dump_prefix)
void UpdatePrimalIntegral()
IntegerValue GetInnerObjectiveUpperBound()
void AddSolutionPostprocessor(std::function< void(CpSolverResponse *)> postprocessor)
IntegerValue SynchronizedInnerObjectiveUpperBound()
IntegerValue SynchronizedInnerObjectiveLowerBound()
void NewSolution(const CpSolverResponse &response, Model *model)
void DisplayImprovementStatistics()
void NotifyThatImprovingProblemIsInfeasible(const std::string &worker_info)
IntegerValue BestSolutionInnerObjectiveValue()
void AddUnsatCore(const std::vector< int > &core)
void SetGapLimitsFromParameters(const SatParameters ¶meters)
const SharedSolutionRepository< int64_t > & SolutionsRepository() const
CpSolverResponse * MutableResponse()
int AddSolutionCallback(std::function< void(const CpSolverResponse &)> callback)
void SetUpdatePrimalIntegralOnEachChange(bool set)
void LoadDebugSolution(Model *)
IntegerValue GetInnerObjectiveLowerBound()
void UnregisterCallback(int callback_id)
SharedResponseManager(Model *model)
void UpdateInnerObjectiveBounds(const std::string &update_info, IntegerValue lb, IntegerValue ub)
void Add(const Solution &solution)
std::vector< Solution > new_solutions_ ABSL_GUARDED_BY(mutex_)
Solution GetRandomBiasedSolution(absl::BitGenRef random) const
SharedSolutionRepository(int num_solutions_to_keep)
Solution GetSolution(int index) const
const int num_solutions_to_keep_
std::vector< int > tmp_indices_ ABSL_GUARDED_BY(mutex_)
std::vector< Solution > solutions_ ABSL_GUARDED_BY(mutex_)
int64_t num_synchronization_ ABSL_GUARDED_BY(mutex_)=0
void AddInternal(const Solution &solution) ABSL_EXCLUSIVE_LOCKS_REQUIRED(mutex_)
ValueType GetVariableValueInSolution(int var_index, int solution_index) const
CpModelProto const * model_proto
SharedResponseManager * response
void STLStableSortAndRemoveDuplicates(T *v, const LessFunc &less_func)
Collection of objects used to extend the Constraint Solver library.
bool operator<(const Solution &other) const
std::vector< ValueType > variable_values
bool operator==(const Solution &other) const