21 #include "absl/synchronization/mutex.h"
41 shared_time_limit_(shared_time_limit),
42 shared_bounds_(shared_bounds),
43 shared_response_(shared_response) {
44 CHECK(shared_response_ !=
nullptr);
45 if (shared_bounds_ !=
nullptr) {
48 *model_proto_with_only_variables_.mutable_variables() =
49 model_proto_.variables();
50 RecomputeHelperData();
55 if (shared_bounds_ !=
nullptr) {
56 std::vector<int> model_variables;
57 std::vector<int64_t> new_lower_bounds;
58 std::vector<int64_t> new_upper_bounds;
60 &new_lower_bounds, &new_upper_bounds);
62 bool new_variables_have_been_fixed =
false;
65 absl::MutexLock domain_lock(&domain_mutex_);
67 for (
int i = 0; i < model_variables.size(); ++i) {
68 const int var = model_variables[i];
69 const int64_t new_lb = new_lower_bounds[i];
70 const int64_t new_ub = new_upper_bounds[i];
73 model_proto_with_only_variables_.variables(
var).domain();
74 const int64_t old_lb = domain.Get(0);
75 const int64_t old_ub = domain.Get(domain.size() - 1);
76 VLOG(3) <<
"Variable: " <<
var <<
" old domain: [" << old_lb <<
", "
77 << old_ub <<
"] new domain: [" << new_lb <<
", " << new_ub
81 model_proto_with_only_variables_.variables(
var));
102 model_proto_with_only_variables_.mutable_variables(
var));
103 new_variables_have_been_fixed |= new_domain.
IsFixed();
108 if (new_variables_have_been_fixed) {
109 RecomputeHelperData();
114 void NeighborhoodGeneratorHelper::RecomputeHelperData() {
122 absl::ReaderMutexLock domain_lock(&domain_mutex_);
124 var_to_constraint_.assign(model_proto_.variables_size(), {});
125 constraint_to_var_.assign(model_proto_.constraints_size(), {});
127 for (
int ct_index = 0; ct_index < model_proto_.constraints_size();
131 if (IsConstant(
var))
continue;
132 var_to_constraint_[
var].push_back(ct_index);
133 constraint_to_var_[ct_index].push_back(
var);
137 if (parameters_.lns_expand_intervals_in_constraint_graph()) {
143 if (IsConstant(
var))
continue;
144 var_to_constraint_[
var].push_back(ct_index);
145 constraint_to_var_[ct_index].push_back(
var);
151 type_to_constraints_.clear();
152 const int num_constraints = model_proto_.constraints_size();
153 for (
int c = 0; c < num_constraints; ++c) {
154 const int type = model_proto_.constraints(c).constraint_case();
155 if (type >= type_to_constraints_.size()) {
156 type_to_constraints_.resize(type + 1);
158 type_to_constraints_[type].push_back(c);
161 active_variables_.clear();
162 active_variables_set_.assign(model_proto_.variables_size(),
false);
164 if (parameters_.lns_focus_on_decision_variables()) {
165 for (
const auto& search_strategy : model_proto_.search_strategy()) {
166 for (
const int var : search_strategy.variables()) {
168 if (!active_variables_set_[pos_var] && !IsConstant(pos_var)) {
169 active_variables_set_[pos_var] =
true;
170 active_variables_.push_back(pos_var);
176 if (!active_variables_.empty())
return;
180 for (
int i = 0; i < model_proto_.variables_size(); ++i) {
181 if (!IsConstant(i)) {
182 active_variables_.push_back(i);
183 active_variables_set_[i] =
true;
189 return active_variables_set_[
var];
192 bool NeighborhoodGeneratorHelper::IsConstant(
int var)
const {
193 return model_proto_with_only_variables_.variables(
var).domain_size() == 2 &&
194 model_proto_with_only_variables_.variables(
var).domain(0) ==
195 model_proto_with_only_variables_.variables(
var).domain(1);
199 const CpModelProto& source_model,
200 const absl::flat_hash_set<int>& fixed_variables_set,
201 const CpSolverResponse& initial_solution,
202 CpModelProto* output_model)
const {
203 output_model->mutable_variables()->Clear();
204 output_model->mutable_variables()->Reserve(source_model.variables_size());
205 for (
int i = 0; i < source_model.variables_size(); ++i) {
206 IntegerVariableProto* var_proto = output_model->add_variables();
207 const IntegerVariableProto& source_var_proto = source_model.variables(i);
209 if (
DEBUG_MODE && !source_var_proto.name().empty()) {
210 var_proto->set_name(source_var_proto.name());
212 if (fixed_variables_set.contains(i)) {
213 const int64_t
value = initial_solution.solution(i);
217 var_proto->add_domain(
value);
218 var_proto->add_domain(
value);
220 *var_proto->mutable_domain() = source_var_proto.domain();
231 absl::ReaderMutexLock lock(&domain_mutex_);
232 *neighborhood.
delta.mutable_variables() =
233 model_proto_with_only_variables_.variables();
239 const CpSolverResponse& initial_solution)
const {
240 std::vector<int> active_intervals;
241 absl::ReaderMutexLock lock(&domain_mutex_);
243 const ConstraintProto& interval_ct =
ModelProto().constraints(i);
247 if (interval_ct.enforcement_literal().size() == 1) {
248 const int enforcement_ref = interval_ct.enforcement_literal(0);
249 const int enforcement_var =
PositiveRef(enforcement_ref);
250 const int value = initial_solution.solution(enforcement_var);
258 if (interval_ct.enforcement_literal().empty() &&
259 IsConstant(
PositiveRef(interval_ct.interval().start())) &&
260 IsConstant(
PositiveRef(interval_ct.interval().size())) &&
261 IsConstant(
PositiveRef(interval_ct.interval().end()))) {
265 active_intervals.push_back(i);
267 return active_intervals;
271 const CpSolverResponse& initial_solution,
272 const std::vector<int>& variables_to_fix)
const {
275 const absl::flat_hash_set<int> fixed_variables_set(variables_to_fix.begin(),
276 variables_to_fix.end());
278 bool copy_is_successful =
true;
280 absl::ReaderMutexLock domain_lock(&domain_mutex_);
282 model_proto_with_only_variables_, fixed_variables_set, initial_solution,
283 &neighborhood.
delta);
286 if (!copy_is_successful) {
295 neighborhood.
is_reduced = !variables_to_fix.empty();
304 const CpSolverResponse& initial_solution, CpModelProto*
model_proto)
const {
308 const IntegerVariableProto& var_proto =
model_proto->variables(
var);
309 return var_proto.domain_size() == 2 &&
310 var_proto.domain(0) == var_proto.domain(1);
313 if (is_fixed(
var))
continue;
317 initial_solution.solution(
var));
322 const std::vector<int>& constraints_to_remove)
const {
325 if (constraints_to_remove.empty())
return neighborhood;
332 const CpSolverResponse& initial_solution,
333 const std::vector<int>& relaxed_variables)
const {
334 std::vector<bool> relaxed_variables_set(model_proto_.variables_size(),
false);
335 for (
const int var : relaxed_variables) relaxed_variables_set[
var] =
true;
336 std::vector<int> fixed_variables;
339 for (
const int i : active_variables_) {
340 if (!relaxed_variables_set[i]) {
341 fixed_variables.push_back(i);
349 const CpSolverResponse& initial_solution)
const {
361 if (num_calls_ <= 10)
return std::numeric_limits<double>::infinity();
362 return current_average_ + sqrt((2 * log(total_num_calls)) / num_calls_);
370 std::sort(solve_data_.begin(), solve_data_.end());
373 int num_fully_solved_in_batch = 0;
374 int num_not_fully_solved_in_batch = 0;
376 for (
const SolveData& data : solve_data_) {
385 ++num_fully_solved_calls_;
386 ++num_fully_solved_in_batch;
388 ++num_not_fully_solved_in_batch;
397 const IntegerValue best_objective_improvement =
399 ? IntegerValue(
CapSub(data.new_objective_bound.value(),
400 data.initial_best_objective_bound.value()))
401 : IntegerValue(
CapSub(data.initial_best_objective.value(),
402 data.new_objective.value()));
403 if (best_objective_improvement > 0) {
404 num_consecutive_non_improving_calls_ = 0;
406 ++num_consecutive_non_improving_calls_;
411 const double gain_per_time_unit =
412 std::max(0.0,
static_cast<double>(best_objective_improvement.value())) /
413 (1.0 + data.deterministic_time);
414 if (num_calls_ <= 100) {
415 current_average_ += (gain_per_time_unit - current_average_) / num_calls_;
417 current_average_ = 0.9 * current_average_ + 0.1 * gain_per_time_unit;
420 deterministic_time_ += data.deterministic_time;
424 difficulty_.
Update(num_not_fully_solved_in_batch,
425 num_fully_solved_in_batch);
433 if (num_consecutive_non_improving_calls_ > 50) {
434 num_consecutive_non_improving_calls_ = 0;
435 deterministic_limit_ *= 1.02;
439 deterministic_limit_ =
std::min(60.0, deterministic_limit_);
447 void GetRandomSubset(
double relative_size, std::vector<int>* base,
448 absl::BitGenRef random) {
449 if (base->empty())
return;
453 std::shuffle(base->begin(), base->end(), random);
454 const int target_size = std::round(relative_size * base->size());
455 base->resize(target_size);
461 const CpSolverResponse& initial_solution,
double difficulty,
462 absl::BitGenRef random) {
464 GetRandomSubset(1.0 -
difficulty, &fixed_variables, random);
469 const CpSolverResponse& initial_solution,
double difficulty,
470 absl::BitGenRef random) {
471 std::vector<int> active_constraints;
474 ConstraintProto::CONSTRAINT_NOT_SET) {
477 active_constraints.push_back(
ct);
482 const int target_size = std::ceil(
difficulty * num_active_vars);
484 if (num_constraints == 0 || target_size == num_active_vars) {
489 std::shuffle(active_constraints.begin(), active_constraints.end(), random);
491 std::vector<bool> visited_variables_set(num_model_vars,
false);
492 std::vector<int> relaxed_variables;
496 for (
const int constraint_index : active_constraints) {
497 CHECK_LT(constraint_index, num_constraints);
499 if (visited_variables_set[
var])
continue;
500 visited_variables_set[
var] =
true;
502 relaxed_variables.push_back(
var);
503 if (relaxed_variables.size() == target_size)
break;
506 if (relaxed_variables.size() == target_size)
break;
513 const CpSolverResponse& initial_solution,
double difficulty,
514 absl::BitGenRef random) {
517 const int target_size = std::ceil(
difficulty * num_active_vars);
518 if (target_size == num_active_vars) {
523 std::vector<bool> visited_variables_set(num_model_vars,
false);
524 std::vector<int> relaxed_variables;
525 std::vector<int> visited_variables;
529 std::vector<bool> scanned_constraints(num_model_constraints,
false);
531 const int first_var =
533 visited_variables_set[first_var] =
true;
534 visited_variables.push_back(first_var);
535 relaxed_variables.push_back(first_var);
537 std::vector<int> random_variables;
540 for (
int i = 0; i < visited_variables.size(); ++i) {
541 random_variables.clear();
545 if (scanned_constraints[
ct])
continue;
546 scanned_constraints[
ct] =
true;
548 if (visited_variables_set[
var])
continue;
549 visited_variables_set[
var] =
true;
550 random_variables.push_back(
var);
555 std::shuffle(random_variables.begin(), random_variables.end(), random);
556 for (
const int var : random_variables) {
557 if (relaxed_variables.size() < target_size) {
558 visited_variables.push_back(
var);
560 relaxed_variables.push_back(
var);
566 if (relaxed_variables.size() >= target_size)
break;
573 const CpSolverResponse& initial_solution,
double difficulty,
574 absl::BitGenRef random) {
577 const int target_size = std::ceil(
difficulty * num_active_vars);
579 if (num_constraints == 0 || target_size == num_active_vars) {
584 std::vector<bool> visited_variables_set(num_model_vars,
false);
585 std::vector<int> relaxed_variables;
586 std::vector<bool> added_constraints(num_constraints,
false);
587 std::vector<int> next_constraints;
590 next_constraints.push_back(absl::Uniform<int>(random, 0, num_constraints));
591 added_constraints[next_constraints.back()] =
true;
593 std::vector<int> random_variables;
596 while (relaxed_variables.size() < target_size) {
598 if (next_constraints.empty())
break;
601 const int i = absl::Uniform<int>(random, 0, next_constraints.size());
602 const int constraint_index = next_constraints[i];
603 std::swap(next_constraints[i], next_constraints.back());
604 next_constraints.pop_back();
608 CHECK_LT(constraint_index, num_constraints);
610 std::shuffle(random_variables.begin(), random_variables.end(), random);
611 for (
const int var : random_variables) {
612 if (visited_variables_set[
var])
continue;
613 visited_variables_set[
var] =
true;
615 relaxed_variables.push_back(
var);
617 if (relaxed_variables.size() == target_size)
break;
620 if (added_constraints[
ct])
continue;
621 added_constraints[
ct] =
true;
622 next_constraints.push_back(
ct);
631 const absl::Span<const int> intervals_to_relax,
632 const CpSolverResponse& initial_solution,
636 (intervals_to_relax.size() <
640 std::set<int> ignored_intervals(intervals_to_relax.begin(),
641 intervals_to_relax.end());
645 if (ignored_intervals.count(i))
continue;
647 const ConstraintProto& interval_ct = helper.
ModelProto().constraints(i);
648 if (interval_ct.enforcement_literal().empty())
continue;
650 CHECK_EQ(interval_ct.enforcement_literal().size(), 1);
651 const int enforcement_ref = interval_ct.enforcement_literal(0);
652 const int enforcement_var =
PositiveRef(enforcement_ref);
653 const int value = initial_solution.solution(enforcement_var);
661 ignored_intervals.insert(i);
666 neighborhood.
delta.mutable_variables(enforcement_var)->clear_domain();
667 neighborhood.
delta.mutable_variables(enforcement_var)->add_domain(
value);
668 neighborhood.
delta.mutable_variables(enforcement_var)->add_domain(
value);
674 std::vector<std::pair<int64_t, int>> start_interval_pairs;
676 helper.
ModelProto().constraints(c).no_overlap().intervals()) {
677 if (ignored_intervals.count(i))
continue;
678 const ConstraintProto& interval_ct = helper.
ModelProto().constraints(i);
681 const int size_var = interval_ct.interval().size();
682 if (initial_solution.solution(size_var) == 0)
continue;
684 const int start_var = interval_ct.interval().start();
685 const int64_t start_value = initial_solution.solution(start_var);
686 start_interval_pairs.push_back({start_value, i});
688 std::sort(start_interval_pairs.begin(), start_interval_pairs.end());
691 for (
int i = 0; i + 1 < start_interval_pairs.size(); ++i) {
693 .constraints(start_interval_pairs[i].second)
697 .constraints(start_interval_pairs[i + 1].second)
700 CHECK_LE(initial_solution.solution(before_var),
701 initial_solution.solution(after_var));
703 LinearConstraintProto* linear =
704 neighborhood.
delta.add_constraints()->mutable_linear();
706 linear->add_domain(0);
707 linear->add_vars(before_var);
708 linear->add_coeffs(1);
709 linear->add_vars(after_var);
710 linear->add_coeffs(-1);
722 const CpSolverResponse& initial_solution,
double difficulty,
723 absl::BitGenRef random) {
724 std::vector<int> intervals_to_relax =
726 GetRandomSubset(
difficulty, &intervals_to_relax, random);
733 const CpSolverResponse& initial_solution,
double difficulty,
734 absl::BitGenRef random) {
735 std::vector<std::pair<int64_t, int>> start_interval_pairs;
736 const std::vector<int> active_intervals =
738 std::vector<int> intervals_to_relax;
742 for (
const int i : active_intervals) {
744 const int start_var = interval_ct.interval().start();
745 const int64_t start_value = initial_solution.solution(start_var);
746 start_interval_pairs.push_back({start_value, i});
748 std::sort(start_interval_pairs.begin(), start_interval_pairs.end());
749 const int relaxed_size = std::floor(
difficulty * start_interval_pairs.size());
751 std::uniform_int_distribution<int> random_var(
752 0, start_interval_pairs.size() - relaxed_size - 1);
753 const int random_start_index = random_var(random);
757 for (
int i = random_start_index; i < relaxed_size; ++i) {
758 intervals_to_relax.push_back(start_interval_pairs[i].second);
766 if (incomplete_solutions_ !=
nullptr) {
770 if (response_manager_ !=
nullptr) {
778 if (lp_solutions_ !=
nullptr && lp_solutions_->
NumSolutions() > 0) {
782 if (relaxation_solutions_ !=
nullptr &&
790 const CpSolverResponse& initial_solution,
double difficulty,
791 absl::BitGenRef random) {
795 const bool lp_solution_available =
796 (lp_solutions_ !=
nullptr && lp_solutions_->
NumSolutions() > 0);
798 const bool relaxation_solution_available =
799 (relaxation_solutions_ !=
nullptr &&
802 const bool incomplete_solution_available =
803 (incomplete_solutions_ !=
nullptr &&
806 if (!lp_solution_available && !relaxation_solution_available &&
807 !incomplete_solution_available) {
815 std::bernoulli_distribution random_bool(0.5);
816 const bool use_lp_relaxation =
817 (lp_solution_available && relaxation_solution_available)
818 ? random_bool(random)
819 : lp_solution_available;
820 if (use_lp_relaxation) {
823 nullptr, lp_solutions_,
824 incomplete_solutions_, random);
826 incomplete_solution_available ?
"incomplete" :
"lp";
828 CHECK(relaxation_solution_available || incomplete_solution_available);
830 response_manager_, relaxation_solutions_,
831 nullptr, incomplete_solutions_, random);
833 incomplete_solution_available ?
"incomplete" :
"relaxation";
843 for (
const std::pair</*model_var*/ int, /*value*/ int64_t> fixed_var :
845 const int var = fixed_var.first;
846 const int64_t
value = fixed_var.second;
847 if (
var >= neighborhood.
delta.variables_size())
continue;
855 neighborhood.
delta.mutable_variables(
var)->clear_domain();
856 neighborhood.
delta.mutable_variables(
var)->add_domain(
value);
857 neighborhood.
delta.mutable_variables(
var)->add_domain(
value);
861 for (
const std::pair<
int,
862 std::pair<int64_t, int64_t>>
864 const int var = reduced_var.first;
865 const int64_t lb = reduced_var.second.first;
866 const int64_t ub = reduced_var.second.second;
867 if (
var >= neighborhood.
delta.variables_size())
continue;
883 const CpSolverResponse& initial_solution,
double difficulty,
884 absl::BitGenRef random) {
885 std::vector<int> removable_constraints;
887 removable_constraints.reserve(num_constraints);
888 for (
int c = 0; c < num_constraints; ++c) {
892 ConstraintProto::kInterval) {
895 removable_constraints.push_back(c);
898 const int target_size =
899 std::round((1.0 -
difficulty) * removable_constraints.size());
901 const int random_start_index =
902 absl::Uniform<int>(random, 0, removable_constraints.size());
903 std::vector<int> removed_constraints;
904 removed_constraints.reserve(target_size);
905 int c = random_start_index;
906 while (removed_constraints.size() < target_size) {
907 removed_constraints.push_back(removable_constraints[c]);
909 if (c == removable_constraints.size()) {
921 std::vector<int> removable_constraints;
923 constraint_weights_.reserve(num_constraints);
925 for (
int c = 0; c < num_constraints; ++c) {
927 case ConstraintProto::kCumulative:
928 case ConstraintProto::kAllDiff:
929 case ConstraintProto::kElement:
930 case ConstraintProto::kRoutes:
931 case ConstraintProto::kCircuit:
932 constraint_weights_.push_back(3.0);
933 num_removable_constraints_++;
935 case ConstraintProto::kBoolOr:
936 case ConstraintProto::kBoolAnd:
937 case ConstraintProto::kBoolXor:
938 case ConstraintProto::kIntProd:
939 case ConstraintProto::kIntDiv:
940 case ConstraintProto::kIntMod:
941 case ConstraintProto::kIntMax:
942 case ConstraintProto::kLinMax:
943 case ConstraintProto::kIntMin:
944 case ConstraintProto::kLinMin:
945 case ConstraintProto::kNoOverlap:
946 case ConstraintProto::kNoOverlap2D:
947 constraint_weights_.push_back(2.0);
948 num_removable_constraints_++;
950 case ConstraintProto::kLinear:
951 case ConstraintProto::kTable:
952 case ConstraintProto::kAutomaton:
953 case ConstraintProto::kInverse:
954 case ConstraintProto::kReservoir:
955 case ConstraintProto::kAtMostOne:
956 case ConstraintProto::kExactlyOne:
957 constraint_weights_.push_back(1.0);
958 num_removable_constraints_++;
960 case ConstraintProto::CONSTRAINT_NOT_SET:
961 case ConstraintProto::kInterval:
964 constraint_weights_.push_back(0.0);
970 void WeightedRandomRelaxationNeighborhoodGenerator::
971 AdditionalProcessingOnSynchronize(
const SolveData& solve_data) {
972 const IntegerValue best_objective_improvement =
973 solve_data.new_objective_bound - solve_data.initial_best_objective_bound;
975 const std::vector<int>& removed_constraints =
976 removed_constraints_[solve_data.neighborhood_id];
990 if (best_objective_improvement > 0) {
992 for (
int c : removed_constraints) {
993 if (constraint_weights_[c] <= 90.0) {
994 constraint_weights_[c] += 10.0;
996 constraint_weights_[c] = 100.0;
1000 best_objective_improvement < 0) {
1002 for (
int c : removed_constraints) {
1003 if (constraint_weights_[c] > 0.5) {
1004 constraint_weights_[c] -= 0.5;
1008 removed_constraints_.erase(solve_data.neighborhood_id);
1012 const CpSolverResponse& initial_solution,
double difficulty,
1013 absl::BitGenRef random) {
1014 const int target_size =
1015 std::round((1.0 -
difficulty) * num_removable_constraints_);
1017 std::vector<int> removed_constraints;
1022 std::vector<std::pair<double, int>> constraint_removal_scores;
1023 std::uniform_real_distribution<double> random_var(0.0, 1.0);
1024 for (
int c = 0; c < constraint_weights_.size(); ++c) {
1025 if (constraint_weights_[c] <= 0)
continue;
1026 const double u = random_var(random);
1027 const double score = std::pow(u, (1 / constraint_weights_[c]));
1028 constraint_removal_scores.push_back({score, c});
1030 std::sort(constraint_removal_scores.rbegin(),
1031 constraint_removal_scores.rend());
1032 for (
int i = 0; i < target_size; ++i) {
1033 removed_constraints.push_back(constraint_removal_scores[i].second);
1039 result.
id = next_available_id_;
1040 next_available_id_++;
1041 removed_constraints_.insert({result.
id, removed_constraints});
#define CHECK_LT(val1, val2)
#define CHECK_EQ(val1, val2)
#define CHECK_GT(val1, val2)
#define DCHECK_GE(val1, val2)
#define DCHECK(condition)
#define CHECK_LE(val1, val2)
#define VLOG(verboselevel)
void Update(int num_decreases, int num_increases)
We call domain any subset of Int64 = [kint64min, kint64max].
bool IsFixed() const
Returns true iff the domain is reduced to a single value.
Domain IntersectionWith(const Domain &domain) const
Returns the intersection of D and domain.
bool IsEmpty() const
Returns true if this is the empty set.
Neighborhood Generate(const CpSolverResponse &initial_solution, double difficulty, absl::BitGenRef random) final
Neighborhood Generate(const CpSolverResponse &initial_solution, double difficulty, absl::BitGenRef random) final
const std::vector< std::vector< int > > & VarToConstraint() const ABSL_SHARED_LOCKS_REQUIRED(graph_mutex_)
NeighborhoodGeneratorHelper(CpModelProto const *model_proto, SatParameters const *parameters, SharedResponseManager *shared_response, SharedTimeLimit *shared_time_limit=nullptr, SharedBoundsManager *shared_bounds=nullptr)
const SharedResponseManager & shared_response() const
Neighborhood FullNeighborhood() const
std::vector< int > ActiveVariables() const
Neighborhood FixAllVariables(const CpSolverResponse &initial_solution) const
int NumActiveVariables() const
Neighborhood FixGivenVariables(const CpSolverResponse &initial_solution, const std::vector< int > &variables_to_fix) const
const absl::Span< const int > TypeToConstraints(ConstraintProto::ConstraintCase type) const
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 CpModelProto & ModelProto() const
const std::vector< std::vector< int > > & ConstraintToVar() const ABSL_SHARED_LOCKS_REQUIRED(graph_mutex_)
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
void Synchronize() override
virtual bool IsRelaxationGenerator() const
absl::Mutex generator_mutex_
virtual bool ReadyToGenerate() const
double difficulty() const
double GetUCBScore(int64_t total_num_calls) const
virtual void AdditionalProcessingOnSynchronize(const SolveData &solve_data)
const NeighborhoodGeneratorHelper & helper_
bool ReadyToGenerate() const override
Neighborhood Generate(const CpSolverResponse &initial_solution, double difficulty, absl::BitGenRef random) final
Neighborhood Generate(const CpSolverResponse &initial_solution, double difficulty, absl::BitGenRef random) final
Neighborhood Generate(const CpSolverResponse &initial_solution, double difficulty, absl::BitGenRef random) final
void GetChangedBounds(int id, std::vector< int > *variables, std::vector< int64_t > *new_lower_bounds, std::vector< int64_t > *new_upper_bounds)
bool HasNewSolution() const
const SharedSolutionRepository< int64_t > & SolutionsRepository() const
Neighborhood Generate(const CpSolverResponse &initial_solution, double difficulty, absl::BitGenRef random) final
Neighborhood Generate(const CpSolverResponse &initial_solution, double difficulty, absl::BitGenRef random) final
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
CpModelProto const * model_proto
void swap(IdMap< K, V > &a, IdMap< K, V > &b)
std::vector< int > UsedVariables(const ConstraintProto &ct)
bool RefIsPositive(int ref)
std::vector< int > UsedIntervals(const ConstraintProto &ct)
bool DomainInProtoContains(const ProtoWithDomain &proto, int64_t value)
void FillDomainInProto(const Domain &domain, ProtoWithDomain *proto)
Domain ReadDomainFromProto(const ProtoWithDomain &proto)
Neighborhood GenerateSchedulingNeighborhoodForRelaxation(const absl::Span< const int > intervals_to_relax, const CpSolverResponse &initial_solution, const NeighborhoodGeneratorHelper &helper)
RINSNeighborhood GetRINSNeighborhood(const SharedResponseManager *response_manager, const SharedRelaxationSolutionRepository *relaxation_solutions, const SharedLPSolutionRepository *lp_solutions, SharedIncompleteSolutionManager *incomplete_solutions, absl::BitGenRef random)
Collection of objects used to extend the Constraint Solver library.
int64_t CapSub(int64_t x, int64_t y)
std::vector< int > constraints_to_ignore
std::vector< std::pair< int, int64_t > > fixed_vars
std::vector< std::pair< int, std::pair< int64_t, int64_t > > > reduced_domain_vars
#define VLOG_IS_ON(verboselevel)