14#ifndef ORTOOLS_SAT_SYNCHRONIZATION_H_
15#define ORTOOLS_SAT_SYNCHRONIZATION_H_
31#include "absl/algorithm/container.h"
32#include "absl/base/thread_annotations.h"
33#include "absl/container/btree_map.h"
34#include "absl/container/flat_hash_map.h"
35#include "absl/container/flat_hash_set.h"
36#include "absl/random/bit_gen_ref.h"
37#include "absl/random/random.h"
38#include "absl/strings/string_view.h"
39#include "absl/synchronization/mutex.h"
40#include "absl/time/time.h"
41#include "absl/types/span.h"
83template <
typename ValueType>
87 absl::string_view name =
"",
147 absl::BitGenRef random)
const;
168 absl::MutexLock mutex_lock(
mutex_);
174 absl::MutexLock mutex_lock(
mutex_);
175 return num_non_improving_;
179 absl::MutexLock mutex_lock(
mutex_);
180 new_solutions_.clear();
186 absl::MutexLock mutex_lock(
mutex_);
191 absl::MutexLock mutex_lock(
mutex_);
239 : best_solutions_(parameters_.solution_pool_size(),
"best_solutions"),
240 alternative_path_(parameters_.alternative_pool_size(),
241 "alternative_path", 0) {
242 best_solutions_.SetDiversityLimit(
247 return best_solutions_;
252 std::shared_ptr<const SharedSolutionRepository<int64_t>::Solution>
256 if (alternative_path_.num_solutions_to_keep() > 0 &&
257 best_solutions_.NumRecentlyNonImproving() > 100 &&
258 absl::Bernoulli(random, 0.5) && alternative_path_.NumSolutions() > 0) {
261 auto result = alternative_path_.GetRandomBiasedSolution(random);
262 if (result !=
nullptr)
return result;
265 if (best_solutions_.NumSolutions() > 0) {
266 return best_solutions_.GetRandomBiasedSolution(random);
271 std::shared_ptr<const SharedSolutionRepository<int64_t>::Solution>
Add(
277 table->push_back(best_solutions_.TableLineStats());
278 table->push_back(alternative_path_.TableLineStats());
295 int64_t max_rank_ ABSL_GUARDED_BY(mutex_) =
296 std::numeric_limits<int64_t>::min();
297 int64_t min_rank_ ABSL_GUARDED_BY(mutex_) =
298 std::numeric_limits<int64_t>::max();
299 std::vector<int64_t> ranks_;
301 std::shared_ptr<const SharedSolutionRepository<int64_t>::Solution>>
302 ABSL_GUARDED_BY(mutex_) seeds_;
321 sol.
rank = num_violations;
339 void AddSolution(
const std::vector<double>& lp_solution);
347 absl::MutexLock mutex_lock(mutex_);
353 mutable absl::Mutex mutex_;
354 std::deque<std::vector<double>> solutions_ ABSL_GUARDED_BY(mutex_);
355 int64_t num_added_ ABSL_GUARDED_BY(mutex_) = 0;
356 mutable int64_t num_queried_ ABSL_GUARDED_BY(mutex_) = 0;
391 std::function<
void(std::vector<int64_t>*)> postprocessor);
464 if (solution_pool_.BestSolutions().NumSolutions() > 0) {
465 return solution_pool_.BestSolutions().GetBestRank();
507 IntegerValue lb, IntegerValue ub);
513 std::shared_ptr<const SharedSolutionRepository<int64_t>::Solution>
514 NewSolution(absl::Span<const int64_t> solution_values,
515 absl::string_view solution_info,
Model* model =
nullptr,
536 return solution_pool_.BestSolutions().NumSolutions() > 0;
545 dump_prefix_ = dump_prefix;
549 void LogMessage(absl::string_view prefix, absl::string_view message);
551 absl::string_view message);
557 return &first_solution_solvers_should_stop_;
565 const std::vector<int64_t>&
DebugSolution()
const {
return debug_solution_; }
568 void TestGapLimitsIfNeeded() ABSL_EXCLUSIVE_LOCKS_REQUIRED(mutex_);
570 ABSL_EXCLUSIVE_LOCKS_REQUIRED(mutex_);
571 void UpdateGapIntegralInternal() ABSL_EXCLUSIVE_LOCKS_REQUIRED(mutex_);
574 ABSL_EXCLUSIVE_LOCKS_REQUIRED(mutex_);
577 ABSL_EXCLUSIVE_LOCKS_REQUIRED(mutex_);
581 absl::Span<const int64_t> variable_values,
582 absl::string_view solution_info) ABSL_EXCLUSIVE_LOCKS_REQUIRED(mutex_);
590 mutable
absl::Mutex mutex_;
593 double absolute_gap_limit_ ABSL_GUARDED_BY(mutex_) = 0.0;
594 double relative_gap_limit_ ABSL_GUARDED_BY(mutex_) = 0.0;
597 CpSolverStatus synchronized_best_status_ ABSL_GUARDED_BY(mutex_) =
599 std::vector<
int> unsat_cores_ ABSL_GUARDED_BY(mutex_);
602 int num_solutions_ ABSL_GUARDED_BY(mutex_) = 0;
603 int64_t inner_objective_lower_bound_ ABSL_GUARDED_BY(mutex_) =
604 std::numeric_limits<int64_t>::min();
605 int64_t inner_objective_upper_bound_ ABSL_GUARDED_BY(mutex_) =
606 std::numeric_limits<int64_t>::max();
607 int64_t best_solution_objective_value_ ABSL_GUARDED_BY(mutex_) =
608 std::numeric_limits<int64_t>::max();
610 bool always_synchronize_ ABSL_GUARDED_BY(mutex_) = true;
611 IntegerValue synchronized_inner_objective_lower_bound_ ABSL_GUARDED_BY(
612 mutex_) = IntegerValue(
std::numeric_limits<int64_t>::min());
613 IntegerValue synchronized_inner_objective_upper_bound_ ABSL_GUARDED_BY(
614 mutex_) = IntegerValue(
std::numeric_limits<int64_t>::max());
616 bool update_integral_on_each_change_ ABSL_GUARDED_BY(mutex_) = false;
617 double gap_integral_ ABSL_GUARDED_BY(mutex_) = 0.0;
618 double last_absolute_gap_ ABSL_GUARDED_BY(mutex_) = 0.0;
619 double last_gap_integral_time_stamp_ ABSL_GUARDED_BY(mutex_) = 0.0;
621 int next_callback_id_ ABSL_GUARDED_BY(mutex_) = 0;
623 callbacks_ ABSL_GUARDED_BY(mutex_);
625 int next_search_log_callback_id_ ABSL_GUARDED_BY(mutex_) = 0;
628 search_log_callbacks_ ABSL_GUARDED_BY(mutex_);
630 int next_best_bound_callback_id_ ABSL_GUARDED_BY(mutex_) = 0;
631 std::vector<
std::pair<
int,
std::function<
void(
double)>>> best_bound_callbacks_
632 ABSL_GUARDED_BY(mutex_);
634 std::vector<
std::function<
void(
std::vector<int64_t>*)>>
635 solution_postprocessors_ ABSL_GUARDED_BY(mutex_);
637 ABSL_GUARDED_BY(mutex_);
639 ABSL_GUARDED_BY(mutex_);
641 statistics_postprocessors_ ABSL_GUARDED_BY(mutex_);
643 status_change_callbacks_ ABSL_GUARDED_BY(mutex_);
646 std::
string dump_prefix_;
649 absl::flat_hash_map<
std::
string,
int> throttling_ids_ ABSL_GUARDED_BY(mutex_);
651 int bounds_logging_id_;
654 std::atomic<
bool> first_solution_solvers_should_stop_ = false;
656 std::vector<int64_t> debug_solution_;
669 absl::Span<const int> variables,
670 absl::Span<const int64_t> new_lower_bounds,
671 absl::Span<const int64_t> new_upper_bounds);
683 absl::Span<const int> variables_to_fix);
693 std::vector<int64_t>* new_lower_bounds,
694 std::vector<int64_t>* new_upper_bounds);
716 dump_prefix_ = dump_prefix;
720 const int num_variables_;
726 std::vector<int64_t> lower_bounds_ ABSL_GUARDED_BY(mutex_);
727 std::vector<int64_t> upper_bounds_ ABSL_GUARDED_BY(mutex_);
729 ABSL_GUARDED_BY(mutex_);
730 int64_t total_num_improvements_ ABSL_GUARDED_BY(mutex_) = 0;
733 std::vector<int64_t> synchronized_lower_bounds_ ABSL_GUARDED_BY(mutex_);
734 std::vector<int64_t> synchronized_upper_bounds_ ABSL_GUARDED_BY(mutex_);
735 std::deque<SparseBitset<int>> id_to_changed_variables_
736 ABSL_GUARDED_BY(mutex_);
741 int64_t num_exported = 0;
742 int64_t num_symmetric = 0;
744 absl::btree_map<std::string, Counters> bounds_exported_
745 ABSL_GUARDED_BY(mutex_);
748 bool has_symmetry_ =
false;
749 std::vector<int> var_to_representative_;
750 std::vector<int> var_to_orbit_index_;
751 CompactVectorVector<int, int> orbits_;
753 std::vector<int64_t> debug_solution_;
754 std::string dump_prefix_;
755 int export_counter_ = 0;
791 bool Add(absl::Span<const int> clause,
int lbd = 2);
806 old_fingerprints_.clear();
807 fingerprints_.clear();
808 fingerprints_.reserve(kMaxFingerprints);
812 int NumLiteralsOfSize(
int size)
const;
813 int NumBufferedLiterals()
const;
819 static size_t HashClause(absl::Span<const int> clause,
size_t hash_seed = 0);
824 constexpr static size_t kMaxFingerprints = 1024 * 1024 /
sizeof(size_t);
825 constexpr static int kNumSizes = kMaxClauseSize - kMinClauseSize + 1;
827 std::vector<int>* MutableBufferForSize(
int size) {
828 return &clauses_by_size_[size - kMinClauseSize];
830 absl::Span<const int> BufferForSize(
int size)
const {
831 return clauses_by_size_[size - kMinClauseSize];
833 absl::Span<const int> NextClause(
int size)
const;
834 void PopClause(
int size);
836 int NumClausesOfSize(
int size)
const;
838 int lbd_threshold_ = kMinLbd;
839 int64_t dropped_literals_since_last_batch_ = 0;
841 absl::flat_hash_set<size_t> fingerprints_;
842 absl::flat_hash_set<size_t> old_fingerprints_;
843 std::array<std::vector<int>, kNumSizes> clauses_by_size_;
870 std::vector<std::pair<int, int>>* new_clauses);
873 int RegisterNewId(absl::string_view worker_name,
bool may_terminate_early);
888 bool ShouldReadBatch(
int reader_id,
int writer_id)
889 ABSL_EXCLUSIVE_LOCKS_REQUIRED(mutex_);
891 static constexpr int kMinBatches = 64;
892 mutable absl::Mutex mutex_;
896 absl::flat_hash_set<std::pair<int, int>> added_binary_clauses_set_
897 ABSL_GUARDED_BY(mutex_);
898 std::vector<std::pair<int, int>> added_binary_clauses_
899 ABSL_GUARDED_BY(mutex_);
900 std::vector<int> id_to_last_processed_binary_clause_ ABSL_GUARDED_BY(mutex_);
901 int last_visible_binary_clause_ ABSL_GUARDED_BY(mutex_) = 0;
906 std::vector<int> id_to_last_returned_batch_ ABSL_GUARDED_BY(mutex_);
907 std::vector<int> id_to_last_finished_batch_ ABSL_GUARDED_BY(mutex_);
909 std::deque<CompactVectorVector<int>> batches_ ABSL_GUARDED_BY(mutex_);
914 std::vector<CompactVectorVector<int>> pending_batches_
915 ABSL_GUARDED_BY(mutex_);
916 int num_full_workers_ ABSL_GUARDED_BY(mutex_) = 0;
918 const bool always_synchronize_ =
true;
921 std::vector<int64_t> id_to_num_exported_ ABSL_GUARDED_BY(mutex_);
922 std::vector<int64_t> id_to_num_imported_ ABSL_GUARDED_BY(mutex_);
923 std::vector<int64_t> id_to_num_updated_ ABSL_GUARDED_BY(mutex_);
924 std::vector<std::string> id_to_worker_name_ ABSL_GUARDED_BY(mutex_);
952 template <
typename H>
954 return H::combine(std::move(h), k.
vars[0], k.
vars[1], k.
coeffs[0],
958 template <
typename Sink>
960 absl::Format(&sink,
"%d X%d + %d X%d", k.
coeffs[0].value(), k.
vars[0],
966 void Add(
int id, Key expr, IntegerValue lb, IntegerValue ub);
972 int RegisterNewImportId(std::string name);
976 std::vector<std::pair<Key, std::pair<IntegerValue, IntegerValue>>>
977 NewlyUpdatedBounds(
int import_id);
983 absl::MutexLock mutex_lock(mutex_);
984 import_id_to_num_imported_[import_id] += num;
988 void MaybeCompressNewlyUpdateKeys() ABSL_EXCLUSIVE_LOCKS_REQUIRED(mutex_);
993 absl::flat_hash_map<Key,
std::pair<IntegerValue, IntegerValue>> shared_bounds_
994 ABSL_GUARDED_BY(mutex_);
1004 std::vector<Key> newly_updated_keys_;
1007 std::vector<
std::
string> import_id_to_name_ ABSL_GUARDED_BY(mutex_);
1008 std::vector<
int> import_id_to_index_ ABSL_GUARDED_BY(mutex_);
1009 std::vector<
int> import_id_to_num_imported_ ABSL_GUARDED_BY(mutex_);
1013 int64_t num_new = 0;
1014 int64_t num_update = 0;
1015 int64_t num_imported = 0;
1016 bool empty()
const {
1017 return num_new == 0 && num_update == 0 && num_imported == 0;
1020 std::vector<Stats> id_to_stats_ ABSL_GUARDED_BY(mutex_);
1021 std::vector<std::string> id_to_worker_name_ ABSL_GUARDED_BY(mutex_);
1030 void AddStats(absl::Span<
const std::pair<std::string, int64_t>> stats);
1037 absl::flat_hash_map<std::string, int64_t> stats_ ABSL_GUARDED_BY(mutex_);
1040template <
typename ValueType>
1042 absl::MutexLock mutex_lock(
mutex_);
1043 return solutions_.size();
1046template <
typename ValueType>
1047std::shared_ptr<const typename SharedSolutionRepository<ValueType>::Solution>
1049 absl::MutexLock mutex_lock(
mutex_);
1050 if (
i >= solutions_.size())
return nullptr;
1052 return solutions_[
i];
1055template <
typename ValueType>
1057 absl::MutexLock mutex_lock(
mutex_);
1058 if (solutions_.empty())
return std::numeric_limits<int64_t>::max();
1059 return solutions_[0]->rank;
1062template <
typename ValueType>
1063std::vector<std::shared_ptr<
1066 absl::MutexLock mutex_lock(
mutex_);
1068 DCHECK(absl::c_is_sorted(solutions_,
1069 [](
const std::shared_ptr<const Solution>& a,
1070 const std::shared_ptr<const Solution>&
b) {
1071 return a->rank <
b->rank;
1073 DCHECK(absl::c_adjacent_find(solutions_,
1074 [](
const std::shared_ptr<const Solution>& a,
1075 const std::shared_ptr<const Solution>&
b) {
1077 }) == solutions_.end());
1078 std::vector<std::shared_ptr<const Solution>> result;
1079 const int num_solutions = std::min(
static_cast<int>(solutions_.size()), n);
1080 result.reserve(num_solutions);
1081 for (
int i = 0;
i < num_solutions; ++
i) {
1082 result.push_back(solutions_[
i]);
1087template <
typename ValueType>
1089 int var_index,
int solution_index)
const {
1090 absl::MutexLock mutex_lock(
mutex_);
1091 return solutions_[solution_index]->variable_values[var_index];
1095template <
typename ValueType>
1096std::shared_ptr<const typename SharedSolutionRepository<ValueType>::Solution>
1098 absl::BitGenRef random)
const {
1099 absl::MutexLock mutex_lock(
mutex_);
1100 if (solutions_.empty())
return nullptr;
1104 if (solutions_.size() > 1) {
1105 const int64_t best_rank = solutions_[0]->rank;
1114 const int kExplorationThreshold = 100;
1117 tmp_indices_.clear();
1118 for (
int i = 0;
i < solutions_.size(); ++
i) {
1119 std::shared_ptr<const Solution>
solution = solutions_[
i];
1121 solution->num_selected <= kExplorationThreshold) {
1122 tmp_indices_.push_back(
i);
1126 if (tmp_indices_.empty()) {
1127 index = absl::Uniform<int>(random, 0, solutions_.size());
1129 index = tmp_indices_[absl::Uniform<int>(random, 0, tmp_indices_.size())];
1134 CHECK_LT(index, solutions_.size());
1135 solutions_[index]->num_selected++;
1136 return solutions_[index];
1139template <
typename ValueType>
1140std::shared_ptr<const typename SharedSolutionRepository<ValueType>::Solution>
1142 std::shared_ptr<Solution> solution_ptr =
1143 std::make_shared<Solution>(std::move(
solution));
1146 absl::MutexLock mutex_lock(
mutex_);
1148 solution_ptr->source_id = source_id_;
1149 new_solutions_.push_back(solution_ptr);
1151 return solution_ptr;
1154template <
typename ValueType>
1157 absl::MutexLock mutex_lock(
mutex_);
1158 if (new_solutions_.empty()) {
1159 const int64_t diff = num_queried_ - num_queried_at_last_sync_;
1160 num_non_improving_ += diff;
1161 num_queried_at_last_sync_ = num_queried_;
1168 [](
const std::shared_ptr<Solution>& a,
1169 const std::shared_ptr<Solution>&
b) {
return *a < *
b; });
1170 for (
const auto& ptr : new_solutions_) {
1175 const int64_t old_best_rank = solutions_.empty()
1176 ? std::numeric_limits<int64_t>::max()
1177 : solutions_[0]->rank;
1179 solutions_.insert(solutions_.end(), new_solutions_.begin(),
1180 new_solutions_.end());
1181 new_solutions_.clear();
1186 &solutions_, [](
const std::shared_ptr<Solution>& a,
1187 const std::shared_ptr<Solution>&
b) {
return *a < *
b; });
1188 const int64_t new_best_rank = solutions_[0]->rank;
1195 while (num_best < solutions_.size() &&
1196 solutions_[num_best]->rank == new_best_rank) {
1205 for (
auto&
solution : solutions_) {
1208 std::swap(solutions_[0],
solution);
1218 const int n = solutions_.size();
1219 distances_.resize(n * n);
1220 const int size = solutions_[0]->variable_values.size();
1221 for (
int i = 0;
i < n; ++
i) {
1222 for (
int j =
i + 1; j < n; ++j) {
1224 for (
int k = 0; k < size; ++k) {
1225 if (solutions_[
i]->variable_values[k] !=
1226 solutions_[j]->variable_values[k]) {
1230 distances_[
i * n + j] = distances_[j * n +
i] = dist;
1243 const std::vector<int> selected =
1247 DCHECK(std::is_sorted(selected.begin(), selected.end()));
1249 for (
const int s : selected) {
1250 solutions_[new_size++] = std::move(solutions_[s]);
1252 solutions_.resize(new_size);
1254 if (VLOG_IS_ON(3)) {
1255 int min_count = std::numeric_limits<int>::max();
1257 for (
const auto& s : solutions_) {
1258 CHECK(s !=
nullptr);
1259 min_count = std::min(s->num_selected, min_count);
1260 max_count = std::max(s->num_selected, max_count);
1263 for (
const int i : selected) {
1264 for (
const int j : selected) {
1265 if (
i > j) score += distances_[
i * n + j];
1268 LOG(INFO) <<
name_ <<
" rank=" << new_best_rank
1270 <<
" orthogonality=" << score <<
" count=[" << min_count
1271 <<
", " << max_count <<
"]";
1279 CHECK(!solutions_.empty());
1280 if (!solutions_.empty()) {
1281 VLOG(4) <<
"Solution pool update:" <<
" num_solutions=" << solutions_.size()
1282 <<
" min_rank=" << solutions_[0]->rank
1283 <<
" max_rank=" << solutions_.back()->rank;
1286 num_synchronization_++;
1287 if (new_best_rank < old_best_rank) {
1288 num_non_improving_ = 0;
1290 const int64_t diff = num_queried_ - num_queried_at_last_sync_;
1291 num_non_improving_ += diff;
1293 num_queried_at_last_sync_ = num_queried_;
1305 bool lrat_check_enabled,
bool drat_check_enabled,
1306 int num_assumed_clauses,
1307 double walltime_in_seconds);
1316 int num_subsolvers_ ABSL_GUARDED_BY(mutex_);
1317 int num_valid_proofs_ ABSL_GUARDED_BY(mutex_);
1318 int num_invalid_proofs_ ABSL_GUARDED_BY(mutex_);
1319 int num_unknown_proofs_ ABSL_GUARDED_BY(mutex_);
1320 bool lrat_check_enabled_ ABSL_GUARDED_BY(mutex_);
1321 bool drat_check_enabled_ ABSL_GUARDED_BY(mutex_);
1322 int num_assumed_clauses_ ABSL_GUARDED_BY(mutex_);
1323 double walltime_in_seconds_ ABSL_GUARDED_BY(mutex_);
1324 std::vector<std::string> proof_filenames_ ABSL_GUARDED_BY(mutex_);
::int32_t solution_pool_diversity_limit() const
void LoadDebugSolution(absl::Span< const int64_t > solution)
int NumBoundsExported(absl::string_view worker_name)
void set_dump_prefix(absl::string_view dump_prefix)
void UpdateDomains(std::vector< Domain > *domains)
void ReportPotentialNewBounds(const std::string &worker_name, absl::Span< const int > variables, absl::Span< const int64_t > new_lower_bounds, absl::Span< const int64_t > new_upper_bounds)
void LogStatistics(SolverLogger *logger)
void FixVariablesFromPartialSolution(absl::Span< const int64_t > solution, absl::Span< const int > variables_to_fix)
void GetChangedBounds(int id, std::vector< int > *variables, std::vector< int64_t > *new_lower_bounds, std::vector< int64_t > *new_upper_bounds)
SharedBoundsManager(const CpModelProto &model_proto)
int RegisterNewId(absl::string_view worker_name, bool may_terminate_early)
void AddBinaryClause(int id, int lit1, int lit2)
void AddBatch(int id, CompactVectorVector< int > batch)
void LogStatistics(SolverLogger *logger)
void GetUnseenBinaryClauses(int id, std::vector< std::pair< int, int > > *new_clauses)
const CompactVectorVector< int > & GetUnseenClauses(int id)
SharedClausesManager(bool always_synchronize)
void NotifyNumImported(int id, int64_t num_imported)
std::vector< double > PopLast()
void AddSolution(const std::vector< double > &lp_solution)
std::vector< std::string > TableLineStats() const
void NewLPSolution(std::vector< double > lp_solution)
SharedLPSolutionRepository(int num_solutions_to_keep)
void LogStatistics(SolverLogger *logger)
void NotifyNumImported(int import_id, int num)
int RegisterNewId(std::string worker_name)
void NewProofFile(absl::string_view filename)
std::vector< std::string > GetProofFilenames()
void Log(SolverLogger *logger)
void NewSubsolverProofStatus(DratChecker::Status status, bool lrat_check_enabled, bool drat_check_enabled, int num_assumed_clauses, double walltime_in_seconds)
SharedLsSolutionRepository()
void AddSolution(std::vector< int64_t > solution, int num_violations)
void AppendResponseToBeMerged(const CpSolverResponse &response)
void AddUnsatCore(const std::vector< int > &core)
IntegerValue GetBestSolutionObjective()
const std::vector< int64_t > & DebugSolution() const
void AddStatisticsPostprocessor(std::function< void(Model *, CpSolverResponse *)> postprocessor)
IntegerValue GetInnerObjectiveLowerBound()
void SetUpdateGapIntegralOnEachChange(bool set)
bool ProblemIsSolved() const
SharedResponseManager(Model *model)
bool HasFeasibleSolution() const
double GapIntegral() const
void LogMessage(absl::string_view prefix, absl::string_view message)
void SetSynchronizationMode(bool always_synchronize)
int AddLogCallback(std::function< std::string(const CpSolverResponse &)> callback)
int AddBestBoundCallback(std::function< void(double)> callback)
void UnregisterLogCallback(int callback_id)
void LoadDebugSolution(absl::Span< const int64_t > solution)
void UnregisterCallback(int callback_id)
IntegerValue BestSolutionInnerObjectiveValue()
void UnregisterBestBoundCallback(int callback_id)
const SharedSolutionPool & SolutionPool() const
void AddStatusChangeCallback(std::function< void(const SolverStatusChangeInfo &)> callback)
bool LoggingIsEnabled() const
void InitializeObjective(const CpModelProto &cp_model)
std::atomic< bool > * first_solution_solvers_should_stop()
void SetGapLimitsFromParameters(const SatParameters ¶meters)
void AddFinalResponsePostprocessor(std::function< void(CpSolverResponse *)> postprocessor)
void set_dump_prefix(absl::string_view dump_prefix)
void AddResponsePostprocessor(std::function< void(CpSolverResponse *)> postprocessor)
CpSolverResponse GetResponse()
int AddSolutionCallback(std::function< void(const CpSolverResponse &)> callback)
IntegerValue GetInnerObjectiveUpperBound()
void AddSolutionPostprocessor(std::function< void(std::vector< int64_t > *)> postprocessor)
void FillSolveStatsInResponse(Model *model, CpSolverResponse *response)
std::shared_ptr< const SharedSolutionRepository< int64_t >::Solution > NewSolution(absl::Span< const int64_t > solution_values, absl::string_view solution_info, Model *model=nullptr, int source_id=-1)
void LogMessageWithThrottling(absl::string_view prefix, absl::string_view message)
void UpdateInnerObjectiveBounds(const std::string &update_info, IntegerValue lb, IntegerValue ub)
void NotifyThatImprovingProblemIsInfeasible(absl::string_view worker_info)
const SharedSolutionRepository< int64_t > & BestSolutions() const
SharedSolutionPool(const SatParameters ¶meters_)
void Synchronize(absl::BitGenRef random)
void AddTableStats(std::vector< std::vector< std::string > > *table) const
std::shared_ptr< const SharedSolutionRepository< int64_t >::Solution > GetSolutionToImprove(absl::BitGenRef random) const
std::shared_ptr< const SharedSolutionRepository< int64_t >::Solution > Add(SharedSolutionRepository< int64_t >::Solution solution)
std::vector< int64_t > ABSL_GUARDED_BY(mutex_) buffer_
std::shared_ptr< const Solution > GetRandomBiasedSolution(absl::BitGenRef random) const
int64_t num_added_ ABSL_GUARDED_BY(mutex_)=0
int64_t num_queried_ ABSL_GUARDED_BY(mutex_)=0
int num_solutions_to_keep() const
std::vector< std::shared_ptr< const Solution > > GetBestNSolutions(int n) const
std::vector< int > tmp_indices_ ABSL_GUARDED_BY(mutex_)
std::shared_ptr< const Solution > GetSolution(int index) const
int64_t NumRecentlyNonImproving() const
std::shared_ptr< const Solution > Add(Solution solution)
int source_id_ ABSL_GUARDED_BY(mutex_)
std::vector< std::shared_ptr< Solution > > new_solutions_ ABSL_GUARDED_BY(mutex_)
void ClearSolutionsAndIncreaseSourceId()
int64_t GetBestRank() const
void SetDiversityLimit(int value)
std::vector< std::shared_ptr< Solution > > solutions_ ABSL_GUARDED_BY(mutex_)
std::vector< std::string > TableLineStats() const
SharedSolutionRepository(int num_solutions_to_keep, absl::string_view name="", int source_id=-1)
const int num_solutions_to_keep_
int64_t num_queried_at_last_sync_ ABSL_GUARDED_BY(mutex_)=0
int64_t num_non_improving_ ABSL_GUARDED_BY(mutex_)=0
std::vector< int64_t > ABSL_GUARDED_BY(mutex_) distances_
void Synchronize(std::function< void(const Solution &solution)> f=nullptr)
ValueType GetVariableValueInSolution(int var_index, int solution_index) const
int64_t num_synchronization_ ABSL_GUARDED_BY(mutex_)=0
void AddStats(absl::Span< const std::pair< std::string, int64_t > > stats)
void Log(SolverLogger *logger)
SharedStatistics()=default
static constexpr int kMaxClauseSize
bool BlockClause(absl::Span< const int > clause)
static constexpr int kMinLbd
UniqueClauseStream(const UniqueClauseStream &)=delete
static constexpr int kMaxLbd
CompactVectorVector< int > NextBatch()
int lbd_threshold() const
bool Add(absl::Span< const int > clause, int lbd=2)
UniqueClauseStream(UniqueClauseStream &&)=default
static constexpr int kMinClauseSize
void set_lbd_threshold(int lbd_threshold)
static constexpr int kMaxLiteralsPerBatch
void STLStableSortAndRemoveDuplicates(T *v, const LessFunc &less_func)
std::vector< int > FindMostDiverseSubset(int k, int n, absl::Span< const int64_t > distances, std::vector< int64_t > &buffer, int always_pick_mask)
std::string FormatName(absl::string_view name)
Select next search node to expand Select next item_i to add this new search node to the search Generate a new search node where item_i is not in the knapsack Check validity of this new partial solution(using propagators) - If valid
std::string FormatCounter(int64_t num)
friend H AbslHashValue(H h, const Key &k)
friend void AbslStringify(Sink &sink, const Key &k)
bool operator==(const Key &o) const
bool operator==(const Solution &other) const
bool operator<(const Solution &other) const
std::vector< ValueType > variable_values
double cur_objective_value_ub
double best_objective_value
double cur_objective_value_lb