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"
45 template <
typename ValueType>
101 void Add(
const Solution& solution);
114 ABSL_EXCLUSIVE_LOCKS_REQUIRED(
mutex_);
163 std::vector<std::vector<double>> solutions_;
164 mutable absl::Mutex mutex_;
197 std::function<
void(
const CpSolverResponse&)>
callback);
242 IntegerValue lb, IntegerValue ub);
297 dump_prefix_ = dump_prefix;
304 void TestGapLimitsIfNeeded() ABSL_EXCLUSIVE_LOCKS_REQUIRED(mutex_);
305 void FillObjectiveValuesInBestResponse()
306 ABSL_EXCLUSIVE_LOCKS_REQUIRED(mutex_);
308 ABSL_EXCLUSIVE_LOCKS_REQUIRED(mutex_);
309 void UpdatePrimalIntegralInternal() ABSL_EXCLUSIVE_LOCKS_REQUIRED(mutex_);
311 void RegisterSolutionFound(const std::
string& improvement_info)
312 ABSL_EXCLUSIVE_LOCKS_REQUIRED(mutex_);
313 void RegisterObjectiveBoundImprovement(const std::
string& improvement_info)
314 ABSL_EXCLUSIVE_LOCKS_REQUIRED(mutex_);
316 const
bool enumerate_all_solutions_;
317 const CpModelProto& model_proto_;
321 mutable
absl::Mutex mutex_;
324 double absolute_gap_limit_ ABSL_GUARDED_BY(mutex_) = 0.0;
325 double relative_gap_limit_ ABSL_GUARDED_BY(mutex_) = 0.0;
327 CpSolverResponse best_response_ ABSL_GUARDED_BY(mutex_);
330 int num_solutions_ ABSL_GUARDED_BY(mutex_) = 0;
331 int64_t inner_objective_lower_bound_ ABSL_GUARDED_BY(mutex_) =
332 std::numeric_limits<int64_t>::
min();
333 int64_t inner_objective_upper_bound_ ABSL_GUARDED_BY(mutex_) =
334 std::numeric_limits<int64_t>::
max();
335 int64_t best_solution_objective_value_ ABSL_GUARDED_BY(mutex_) =
336 std::numeric_limits<int64_t>::
max();
338 IntegerValue synchronized_inner_objective_lower_bound_ ABSL_GUARDED_BY(
339 mutex_) = IntegerValue(std::numeric_limits<int64_t>::
min());
340 IntegerValue synchronized_inner_objective_upper_bound_ ABSL_GUARDED_BY(
341 mutex_) = IntegerValue(std::numeric_limits<int64_t>::
max());
343 bool update_integral_on_each_change_ ABSL_GUARDED_BY(mutex_) = false;
344 double primal_integral_ ABSL_GUARDED_BY(mutex_) = 0.0;
345 double last_absolute_gap_ ABSL_GUARDED_BY(mutex_) = 0.0;
346 double last_primal_integral_time_stamp_ ABSL_GUARDED_BY(mutex_) = 0.0;
348 int next_callback_id_ ABSL_GUARDED_BY(mutex_) = 0;
349 std::vector<std::pair<
int, std::function<
void(const CpSolverResponse&)>>>
350 callbacks_ ABSL_GUARDED_BY(mutex_);
353 std::
string dump_prefix_;
356 std::map<std::
string,
int> primal_improvements_count_ ABSL_GUARDED_BY(mutex_);
357 std::map<std::
string,
int> dual_improvements_count_ ABSL_GUARDED_BY(mutex_);
371 void ReportPotentialNewBounds(
const CpModelProto&
model_proto,
372 const std::string& worker_name,
373 const std::vector<int>& variables,
374 const std::vector<int64_t>& new_lower_bounds,
375 const std::vector<int64_t>& new_upper_bounds);
384 void GetChangedBounds(
int id, std::vector<int>* variables,
385 std::vector<int64_t>* new_lower_bounds,
386 std::vector<int64_t>* new_upper_bounds);
393 const int num_variables_;
394 const CpModelProto& model_proto_;
399 std::vector<int64_t> lower_bounds_ ABSL_GUARDED_BY(mutex_);
400 std::vector<int64_t> upper_bounds_ ABSL_GUARDED_BY(mutex_);
402 ABSL_GUARDED_BY(mutex_);
405 std::vector<int64_t> synchronized_lower_bounds_ ABSL_GUARDED_BY(mutex_);
406 std::vector<int64_t> synchronized_upper_bounds_ ABSL_GUARDED_BY(mutex_);
407 std::deque<SparseBitset<int64_t>> id_to_changed_variables_
408 ABSL_GUARDED_BY(mutex_);
411 template <
typename ValueType>
413 absl::MutexLock mutex_lock(&mutex_);
414 return solutions_.size();
417 template <
typename ValueType>
420 absl::MutexLock mutex_lock(&mutex_);
421 return solutions_[i];
424 template <
typename ValueType>
426 int var_index,
int solution_index)
const {
427 absl::MutexLock mutex_lock(&mutex_);
428 return solutions_[solution_index].variable_values[var_index];
432 template <
typename ValueType>
435 absl::BitGenRef random)
const {
436 absl::MutexLock mutex_lock(&mutex_);
437 const int64_t best_rank = solutions_[0].rank;
446 const int kExplorationThreshold = 100;
449 tmp_indices_.clear();
450 for (
int i = 0; i < solutions_.size(); ++i) {
451 const auto& solution = solutions_[i];
452 if (solution.rank == best_rank &&
453 solution.num_selected <= kExplorationThreshold) {
454 tmp_indices_.push_back(i);
459 if (tmp_indices_.empty()) {
460 index = absl::Uniform<int>(random, 0, solutions_.size());
462 index = tmp_indices_[absl::Uniform<int>(random, 0, tmp_indices_.size())];
464 solutions_[
index].num_selected++;
465 return solutions_[
index];
468 template <
typename ValueType>
470 absl::MutexLock mutex_lock(&mutex_);
471 AddInternal(solution);
474 template <
typename ValueType>
477 int worse_solution_index = 0;
478 for (
int i = 0; i < new_solutions_.size(); ++i) {
480 if (new_solutions_[i] == solution)
return;
481 if (new_solutions_[worse_solution_index] < new_solutions_[i]) {
482 worse_solution_index = i;
485 if (new_solutions_.size() < num_solutions_to_keep_) {
486 new_solutions_.push_back(solution);
487 }
else if (solution < new_solutions_[worse_solution_index]) {
488 new_solutions_[worse_solution_index] = solution;
492 template <
typename ValueType>
494 absl::MutexLock mutex_lock(&mutex_);
495 solutions_.insert(solutions_.end(), new_solutions_.begin(),
496 new_solutions_.end());
497 new_solutions_.clear();
504 if (solutions_.size() > num_solutions_to_keep_) {
505 solutions_.resize(num_solutions_to_keep_);
507 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
SharedSolutionRepository< int64_t > * MutableSolutionsRepository()
CpSolverResponse GetResponse()
void SetStatsFromModel(Model *model)
double PrimalIntegral() const
const SharedSolutionRepository< int64_t > & SolutionsRepository() const
void set_dump_prefix(const std::string &dump_prefix)
void UpdatePrimalIntegral()
SharedResponseManager(bool enumerate_all_solutions, const CpModelProto *proto, const WallTimer *wall_timer, SharedTimeLimit *shared_time_limit, SolverLogger *logger)
IntegerValue GetInnerObjectiveUpperBound()
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)
int AddSolutionCallback(std::function< void(const CpSolverResponse &)> callback)
void SetUpdatePrimalIntegralOnEachChange(bool set)
void LoadDebugSolution(Model *)
IntegerValue GetInnerObjectiveLowerBound()
void UnregisterCallback(int callback_id)
void UpdateInnerObjectiveBounds(const std::string &update_info, IntegerValue lb, IntegerValue ub)
void Add(const Solution &solution)
Solution GetRandomBiasedSolution(absl::BitGenRef random) const
std::vector< int > tmp_indices_ ABSL_GUARDED_BY(mutex_)
SharedSolutionRepository(int num_solutions_to_keep)
Solution GetSolution(int index) const
const int num_solutions_to_keep_
int64_t num_synchronization_ ABSL_GUARDED_BY(mutex_)=0
std::vector< Solution > new_solutions_ ABSL_GUARDED_BY(mutex_)
void AddInternal(const Solution &solution) ABSL_EXCLUSIVE_LOCKS_REQUIRED(mutex_)
ValueType GetVariableValueInSolution(int var_index, int solution_index) const
std::vector< Solution > solutions_ ABSL_GUARDED_BY(mutex_)
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