remove NestedSolve(), Solve() is available even when nested, added SOlveAndCommit() available when nested, NewSearch() is also possible when nested
This commit is contained in:
@@ -861,7 +861,8 @@ class Search {
|
||||
decision_builder_(NULL), created_by_solve_(false),
|
||||
selector_(NULL), search_depth_(0), left_search_depth_(0),
|
||||
should_restart_(false), should_finish_(false),
|
||||
sentinel_pushed_(0), jmpbuf_filled_(false) {}
|
||||
sentinel_pushed_(0), jmpbuf_filled_(false),
|
||||
restore_(true) {}
|
||||
|
||||
// Constructor for a dummy search. The only difference between a dummy search
|
||||
// and a regular one is that the search depth and left search depth is
|
||||
@@ -871,7 +872,8 @@ class Search {
|
||||
decision_builder_(NULL), created_by_solve_(false),
|
||||
selector_(NULL), search_depth_(-1), left_search_depth_(-1),
|
||||
should_restart_(false), should_finish_(false),
|
||||
sentinel_pushed_(0), jmpbuf_filled_(false) {}
|
||||
sentinel_pushed_(0), jmpbuf_filled_(false),
|
||||
restore_(true) {}
|
||||
|
||||
~Search() {
|
||||
STLDeleteElements(&marker_stack_);
|
||||
@@ -918,6 +920,8 @@ class Search {
|
||||
void RightMove() {
|
||||
search_depth_++;
|
||||
}
|
||||
bool restore() const { return restore_; }
|
||||
void set_restore(bool restore) { restore_ = restore; }
|
||||
int search_depth() const { return search_depth_; }
|
||||
void set_search_depth(int d) { search_depth_ = d; }
|
||||
int left_search_depth() const { return left_search_depth_; }
|
||||
@@ -954,6 +958,7 @@ class Search {
|
||||
bool should_finish_;
|
||||
int sentinel_pushed_;
|
||||
bool jmpbuf_filled_;
|
||||
bool restore_;
|
||||
};
|
||||
|
||||
// Backtrack is implemented using 3 primitives:
|
||||
@@ -1090,6 +1095,7 @@ void Search::Clear() {
|
||||
search_depth_ = 0;
|
||||
left_search_depth_ = 0;
|
||||
selector_.reset(NULL);
|
||||
restore_ = true;
|
||||
}
|
||||
|
||||
void Search::EnterSearch() {
|
||||
@@ -1885,18 +1891,31 @@ void Solver::NewSearch(DecisionBuilder* const db,
|
||||
int size) {
|
||||
// TODO(user) : reset statistics
|
||||
|
||||
// ----- gets or creates the search object -----
|
||||
|
||||
CHECK_NOTNULL(db);
|
||||
DCHECK_GE(size, 0);
|
||||
const bool nested = state_ == IN_SEARCH;
|
||||
|
||||
if (state_ == IN_SEARCH || state_ == IN_ROOT_NODE) {
|
||||
LOG(FATAL) << "Use NestedSolve() inside search";
|
||||
if (state_ == IN_ROOT_NODE) {
|
||||
LOG(FATAL) << "Cannot start new searches here.";
|
||||
}
|
||||
// Check state and go to OUTSIDE_SEARCH.
|
||||
Search* const search = searches_.back();
|
||||
|
||||
Search* const search = nested ? new Search(this) : searches_.back();
|
||||
search->set_created_by_solve(false); // default behavior.
|
||||
|
||||
BacktrackToSentinel(INITIAL_SEARCH_SENTINEL);
|
||||
state_ = OUTSIDE_SEARCH;
|
||||
// ----- jumps to correct state -----
|
||||
|
||||
if (nested) {
|
||||
DCHECK_GE(searches_.size(), 2);
|
||||
searches_.push_back(search);
|
||||
} else {
|
||||
DCHECK_EQ(2, searches_.size());
|
||||
BacktrackToSentinel(INITIAL_SEARCH_SENTINEL);
|
||||
state_ = OUTSIDE_SEARCH;
|
||||
}
|
||||
|
||||
// ----- manages all monitors -----
|
||||
|
||||
// Always install the main propagation monitor.
|
||||
propagation_monitor_->Install();
|
||||
@@ -1921,22 +1940,25 @@ void Solver::NewSearch(DecisionBuilder* const db,
|
||||
// Install the print trace if needed.
|
||||
// The print_trace needs to be last to detect propagation from the objective.
|
||||
if (FLAGS_cp_trace_propagation) {
|
||||
print_trace_ = BuildPrintTrace(this);
|
||||
if (!nested) { // Build trace objet at top level.
|
||||
print_trace_ = BuildPrintTrace(this);
|
||||
}
|
||||
print_trace_->Install();
|
||||
} else {
|
||||
// This is useful to trace the exact behavior of the search.
|
||||
// The '######## ' prefix is the same as the progagation trace.
|
||||
if (FLAGS_cp_trace_search) {
|
||||
if (FLAGS_cp_trace_search && !nested) {
|
||||
SearchMonitor* const trace = MakeSearchTrace("######## ");
|
||||
trace->Install();
|
||||
}
|
||||
print_trace_ = NULL;
|
||||
}
|
||||
|
||||
// ----- enters search -----
|
||||
|
||||
search->EnterSearch();
|
||||
|
||||
// Push sentinel and set decision builder.
|
||||
DCHECK_EQ(2, searches_.size());
|
||||
PushSentinel(INITIAL_SEARCH_SENTINEL);
|
||||
search->set_decision_builder(db);
|
||||
}
|
||||
@@ -2281,22 +2303,33 @@ bool Solver::NextSolution() {
|
||||
}
|
||||
|
||||
void Solver::EndSearch() {
|
||||
CHECK_EQ(2, searches_.size());
|
||||
Search* const search = searches_.back();
|
||||
BacktrackToSentinel(INITIAL_SEARCH_SENTINEL);
|
||||
if (search->restore()) {
|
||||
BacktrackToSentinel(INITIAL_SEARCH_SENTINEL);
|
||||
} else {
|
||||
CHECK_GT(searches_.size(), 2);
|
||||
if (search->sentinel_pushed_ > 0) {
|
||||
JumpToSentinelWhenNested();
|
||||
}
|
||||
}
|
||||
search->ExitSearch();
|
||||
search->Clear();
|
||||
state_ = OUTSIDE_SEARCH;
|
||||
if (!FLAGS_cp_profile_file.empty()) {
|
||||
LOG(INFO) << "Exporting profile to " << FLAGS_cp_profile_file;
|
||||
ExportProfilingOverview(FLAGS_cp_profile_file);
|
||||
if (2 == searches_.size()) { // Post top level search actions.
|
||||
state_ = OUTSIDE_SEARCH;
|
||||
if (!FLAGS_cp_profile_file.empty()) {
|
||||
LOG(INFO) << "Exporting profile to " << FLAGS_cp_profile_file;
|
||||
ExportProfilingOverview(FLAGS_cp_profile_file);
|
||||
}
|
||||
} else { // We clean the nested Search.
|
||||
delete search;
|
||||
searches_.pop_back();
|
||||
}
|
||||
}
|
||||
|
||||
bool Solver::CheckAssignment(Assignment* const solution) {
|
||||
CHECK(solution);
|
||||
if (state_ == IN_SEARCH || state_ == IN_ROOT_NODE) {
|
||||
LOG(FATAL) << "Use NestedSolve() inside search";
|
||||
LOG(FATAL) << "CheckAssignment is only available at the top level.";
|
||||
}
|
||||
// Check state and go to OUTSIDE_SEARCH.
|
||||
Search* const search = searches_.back();
|
||||
@@ -2373,93 +2406,52 @@ bool Solver::CheckConstraint(Constraint* const ct) {
|
||||
return Solve(MakeConstraintAdder(ct));
|
||||
}
|
||||
|
||||
bool Solver::NestedSolve(DecisionBuilder* const db,
|
||||
bool restore,
|
||||
const std::vector<SearchMonitor*>& monitors) {
|
||||
return NestedSolve(db, restore, monitors.data(), monitors.size());
|
||||
bool Solver::SolveAndCommit(DecisionBuilder* const db,
|
||||
const std::vector<SearchMonitor*>& monitors) {
|
||||
return SolveAndCommit(db, monitors.data(), monitors.size());
|
||||
}
|
||||
|
||||
bool Solver::NestedSolve(DecisionBuilder* const db,
|
||||
bool restore,
|
||||
SearchMonitor* const m1) {
|
||||
bool Solver::SolveAndCommit(DecisionBuilder* const db,
|
||||
SearchMonitor* const m1) {
|
||||
std::vector<SearchMonitor*> monitors;
|
||||
monitors.push_back(m1);
|
||||
return NestedSolve(db, restore, monitors.data(), monitors.size());
|
||||
return SolveAndCommit(db, monitors.data(), monitors.size());
|
||||
}
|
||||
|
||||
bool Solver::NestedSolve(DecisionBuilder* const db, bool restore) {
|
||||
return NestedSolve(db, restore, NULL, Zero());
|
||||
bool Solver::SolveAndCommit(DecisionBuilder* const db) {
|
||||
return SolveAndCommit(db, NULL, Zero());
|
||||
}
|
||||
|
||||
bool Solver::NestedSolve(DecisionBuilder* const db,
|
||||
bool restore,
|
||||
SearchMonitor* const m1,
|
||||
SearchMonitor* const m2) {
|
||||
bool Solver::SolveAndCommit(DecisionBuilder* const db,
|
||||
SearchMonitor* const m1,
|
||||
SearchMonitor* const m2) {
|
||||
std::vector<SearchMonitor*> monitors;
|
||||
monitors.push_back(m1);
|
||||
monitors.push_back(m2);
|
||||
return NestedSolve(db, restore, monitors.data(), monitors.size());
|
||||
return SolveAndCommit(db, monitors.data(), monitors.size());
|
||||
}
|
||||
|
||||
bool Solver::NestedSolve(DecisionBuilder* const db,
|
||||
bool restore,
|
||||
SearchMonitor* const m1,
|
||||
SearchMonitor* const m2,
|
||||
SearchMonitor* const m3) {
|
||||
bool Solver::SolveAndCommit(DecisionBuilder* const db,
|
||||
SearchMonitor* const m1,
|
||||
SearchMonitor* const m2,
|
||||
SearchMonitor* const m3) {
|
||||
std::vector<SearchMonitor*> monitors;
|
||||
monitors.push_back(m1);
|
||||
monitors.push_back(m2);
|
||||
monitors.push_back(m3);
|
||||
return NestedSolve(db, restore, monitors.data(), monitors.size());
|
||||
return SolveAndCommit(db, monitors.data(), monitors.size());
|
||||
}
|
||||
|
||||
bool Solver::NestedSolve(DecisionBuilder* const db,
|
||||
bool restore,
|
||||
SearchMonitor* const * monitors,
|
||||
int size) {
|
||||
Search new_search(this);
|
||||
searches_.push_back(&new_search);
|
||||
// Always install the main propagation monitor.
|
||||
propagation_monitor_->Install();
|
||||
// Install the demon monitor if needed.
|
||||
if (demon_profiler_ != NULL) {
|
||||
InstallDemonProfiler(demon_profiler_);
|
||||
}
|
||||
|
||||
for (int i = 0; i < size; ++i) {
|
||||
if (monitors[i] != NULL) {
|
||||
monitors[i]->Install();
|
||||
}
|
||||
}
|
||||
std::vector<SearchMonitor*> extras;
|
||||
db->AppendMonitors(this, &extras);
|
||||
for (ConstIter<std::vector<SearchMonitor*> > it(extras); !it.at_end(); ++it) {
|
||||
SearchMonitor* const monitor = *it;
|
||||
if (monitor != NULL) {
|
||||
monitor->Install();
|
||||
}
|
||||
}
|
||||
// Install the print trace if needed.
|
||||
if (print_trace_ != NULL) {
|
||||
print_trace_->Install();
|
||||
}
|
||||
|
||||
bool Solver::SolveAndCommit(DecisionBuilder* const db,
|
||||
SearchMonitor* const * monitors,
|
||||
int size) {
|
||||
NewSearch(db, monitors, size);
|
||||
searches_.back()->set_created_by_solve(true); // Overwrites default.
|
||||
new_search.EnterSearch();
|
||||
PushSentinel(INITIAL_SEARCH_SENTINEL);
|
||||
new_search.set_decision_builder(db);
|
||||
bool res = NextSolution();
|
||||
if (res) {
|
||||
if (restore) {
|
||||
BacktrackToSentinel(INITIAL_SEARCH_SENTINEL);
|
||||
} else {
|
||||
JumpToSentinelWhenNested();
|
||||
}
|
||||
}
|
||||
new_search.ExitSearch();
|
||||
new_search.Clear();
|
||||
searches_.pop_back();
|
||||
return res;
|
||||
searches_.back()->set_restore(false);
|
||||
NextSolution();
|
||||
const bool solution_found = searches_.back()->solution_counter() > 0;
|
||||
EndSearch();
|
||||
return solution_found;
|
||||
}
|
||||
|
||||
void Solver::Fail() {
|
||||
|
||||
@@ -908,8 +908,8 @@ class Solver {
|
||||
// assigning any variable to any value is a solution, unless the root node
|
||||
// propagation discovers that the model is infeasible.
|
||||
//
|
||||
// These function must be called from outside of search, meaning that
|
||||
// <tt>state() == OUTSIDE_SEARCH</tt>.
|
||||
// These function must be called from either from outside of search,
|
||||
// or withing the Next() method of a decion builder.
|
||||
//
|
||||
// Solve will terminate whenever any of the following event arise:
|
||||
// * A search monitor asks the solver to terminate the search by calling
|
||||
@@ -951,13 +951,14 @@ class Solver {
|
||||
// @}
|
||||
|
||||
// @{
|
||||
// Decomposed top level search.
|
||||
// The code should look like
|
||||
// Decomposed search.
|
||||
// The code for a top level search should look like
|
||||
// solver->NewSearch(db);
|
||||
// while (solver->NextSolution()) {
|
||||
// //.. use the current solution
|
||||
// }
|
||||
// solver()->EndSearch();
|
||||
|
||||
void NewSearch(DecisionBuilder* const db,
|
||||
const std::vector<SearchMonitor*>& monitors);
|
||||
void NewSearch(DecisionBuilder* const db,
|
||||
@@ -982,37 +983,34 @@ class Solver {
|
||||
void EndSearch();
|
||||
// @}
|
||||
|
||||
|
||||
// Nested solve using a decision builder and up to three
|
||||
// SolveAndCommit using a decision builder and up to three
|
||||
// search monitors, usually one for the objective, one for the limits
|
||||
// and one to collect solutions.
|
||||
// The restore parameter indicates if the search should backtrack completely
|
||||
// after completion, even in case of success.
|
||||
bool NestedSolve(DecisionBuilder* const db,
|
||||
bool restore,
|
||||
const std::vector<SearchMonitor*>& monitors);
|
||||
bool NestedSolve(DecisionBuilder* const db,
|
||||
bool restore,
|
||||
SearchMonitor* const * monitors,
|
||||
int size);
|
||||
bool NestedSolve(DecisionBuilder* const db, bool restore);
|
||||
bool NestedSolve(DecisionBuilder* const db,
|
||||
bool restore,
|
||||
SearchMonitor* const m1);
|
||||
bool NestedSolve(DecisionBuilder* const db,
|
||||
bool restore,
|
||||
SearchMonitor* const m1, SearchMonitor* const m2);
|
||||
bool NestedSolve(DecisionBuilder* const db,
|
||||
bool restore,
|
||||
SearchMonitor* const m1,
|
||||
SearchMonitor* const m2,
|
||||
SearchMonitor* const m3);
|
||||
//
|
||||
// The difference between a SolveAndCommit() and a Solve() method
|
||||
// call is the fact that SolveAndCommit will not backtrack all
|
||||
// modifications at the end of the search. This method is only
|
||||
// usable during the Next() method of a decision builder.
|
||||
bool SolveAndCommit(DecisionBuilder* const db,
|
||||
const std::vector<SearchMonitor*>& monitors);
|
||||
bool SolveAndCommit(DecisionBuilder* const db,
|
||||
SearchMonitor* const * monitors,
|
||||
int size);
|
||||
bool SolveAndCommit(DecisionBuilder* const db);
|
||||
bool SolveAndCommit(DecisionBuilder* const db,
|
||||
SearchMonitor* const m1);
|
||||
bool SolveAndCommit(DecisionBuilder* const db,
|
||||
SearchMonitor* const m1, SearchMonitor* const m2);
|
||||
bool SolveAndCommit(DecisionBuilder* const db,
|
||||
SearchMonitor* const m1,
|
||||
SearchMonitor* const m2,
|
||||
SearchMonitor* const m3);
|
||||
|
||||
// Checks whether the given assignment satisfies all the relevant constraints.
|
||||
bool CheckAssignment(Assignment* const assignment);
|
||||
|
||||
// Checks whether adding this constraint will lead to an immediate
|
||||
// failure. It will return true if the model is already
|
||||
// failure. It will return false if the model is already
|
||||
// inconsistent, or if adding the constraint makes it inconsistent.
|
||||
bool CheckConstraint(Constraint* const constraint);
|
||||
|
||||
@@ -1513,9 +1511,7 @@ class Solver {
|
||||
|
||||
|
||||
// |{i | v[i] == value}| == count
|
||||
Constraint* MakeCount(const std::vector<IntVar*>& v,
|
||||
int64 value,
|
||||
int64 count);
|
||||
Constraint* MakeCount(const std::vector<IntVar*>& v, int64 value, int64 count);
|
||||
// |{i | v[i] == value}| == count
|
||||
Constraint* MakeCount(const std::vector<IntVar*>& v, int64 value,
|
||||
IntVar* const count);
|
||||
@@ -2765,8 +2761,7 @@ class Solver {
|
||||
int SearchLeftDepth() const;
|
||||
|
||||
// Gets the number of nested searches. It returns 0 outside search,
|
||||
// 1 during the top level search, 2 if one level of NestedSolve() is
|
||||
// used, and more if more solves are nested.
|
||||
// 1 during the top level search, 2 or more in case of nested searched.
|
||||
int SolveDepth() const;
|
||||
|
||||
// Sets the given branch selector on the current active search.
|
||||
|
||||
@@ -924,7 +924,6 @@ static void SetPythonFlags(bool trace_propagation,
|
||||
PhaseStrategy str);
|
||||
%ignore Solver::Solve(DecisionBuilder* const db,
|
||||
SearchMonitor* const * monitors, int size);
|
||||
%ignore Solver::NestedSolve;
|
||||
%ignore Solver::Compose(DecisionBuilder* const db1,
|
||||
DecisionBuilder* const db2);
|
||||
%ignore Solver::Compose(DecisionBuilder* const db1,
|
||||
|
||||
@@ -394,8 +394,8 @@ class ImpactRecorder {
|
||||
}
|
||||
// Reset the number of impacts initialized.
|
||||
init_count_ = 0;
|
||||
// Use NestedSolve() to scan all values of one variable.
|
||||
solver->NestedSolve(init_decision_builder, true);
|
||||
// Use Solve() to scan all values of one variable.
|
||||
solver->Solve(init_decision_builder);
|
||||
|
||||
// If we have not initialized all values, then they can be removed.
|
||||
// As the iterator is not stable w.r.t. deletion, we need to store
|
||||
@@ -1069,7 +1069,7 @@ class ImpactDecisionBuilder : public DecisionBuilder {
|
||||
HeuristicWrapper* const wrapper = heuristics_[index];
|
||||
|
||||
const bool result =
|
||||
solver->NestedSolve(wrapper->phase, false, heuristic_limit_);
|
||||
solver->SolveAndCommit(wrapper->phase, heuristic_limit_);
|
||||
if (result && parameters_.display_level != DefaultPhaseParameters::NONE) {
|
||||
LOG(INFO) << "Solution found by heuristic " << wrapper->name;
|
||||
}
|
||||
|
||||
@@ -4377,6 +4377,7 @@ IntVar* Solver::MakeIntConst(int64 val) {
|
||||
|
||||
namespace {
|
||||
string IndexedName(const string& prefix, int index, int max_index) {
|
||||
#if 0
|
||||
#if defined(_MSC_VER)
|
||||
const int digits = max_index > 0 ?
|
||||
static_cast<int>(log(1.0L * max_index) / log(10.0L)) + 1 :
|
||||
@@ -4385,6 +4386,9 @@ string IndexedName(const string& prefix, int index, int max_index) {
|
||||
const int digits = max_index > 0 ? static_cast<int>(log10(max_index)) + 1: 1;
|
||||
#endif
|
||||
return StringPrintf("%s%0*d", prefix.c_str(), digits, index);
|
||||
#else
|
||||
return StringPrintf("%s%d", prefix.c_str(), index);
|
||||
#endif
|
||||
}
|
||||
} // namespace
|
||||
|
||||
|
||||
@@ -108,13 +108,13 @@ class GccConstraint : public Constraint {
|
||||
for (i = 2; i < count + 2; i++) {
|
||||
sum_[i + 1] = sum_[i] + elements[i - 2];
|
||||
}
|
||||
sum_[i + 1] = sum_[i] + 1;
|
||||
sum_[i + 2] = sum_[i + 1] + 1;
|
||||
sum_[count + 3] = sum_[i] + 1;
|
||||
sum_[count + 4] = sum_[i + 1] + 1;
|
||||
|
||||
i = count + 3;
|
||||
j = i;
|
||||
while (i > 0) {
|
||||
while (sum_[i] == sum_[i-1]) {
|
||||
while (sum_[i] == sum_[i - 1]) {
|
||||
ds_[i--] = j;
|
||||
}
|
||||
ds_[j] = i--;
|
||||
@@ -144,10 +144,10 @@ class GccConstraint : public Constraint {
|
||||
int64 Sum(int64 from, int64 to) const {
|
||||
if (from <= to) {
|
||||
DCHECK((offset_ <= from) && (to <= last_value_));
|
||||
return sum_[to - offset_] - sum_[from - offset_ - 1];
|
||||
return sum_[to - offset_] - sum_[from -1 - offset_];
|
||||
} else {
|
||||
DCHECK((offset_ <= to) && (from <= last_value_));
|
||||
return sum_[to - offset_ - 1] - sum_[from - offset_];
|
||||
return sum_[to - 1 - offset_] - sum_[from - offset_];
|
||||
}
|
||||
}
|
||||
|
||||
@@ -418,30 +418,30 @@ class GccConstraint : public Constraint {
|
||||
bounds_[0] = last;
|
||||
|
||||
// merge sorted_by_min_[] and sorted_by_max_[] into bounds_[]
|
||||
int64 i = 0;
|
||||
int64 j = 0;
|
||||
int64 min_index = 0;
|
||||
int64 max_index = 0;
|
||||
int64 active_index = 0;
|
||||
for (;;) {
|
||||
// make sure sorted_by_min_ exhausted first
|
||||
if (i < size_ && min <= max) {
|
||||
if (min_index < size_ && min <= max) {
|
||||
if (min != last) {
|
||||
bounds_[++active_index] = min;
|
||||
last = min;
|
||||
}
|
||||
sorted_by_min_[i]->min_rank = active_index;
|
||||
if (++i < size_) {
|
||||
min = sorted_by_min_[i]->min_value;
|
||||
sorted_by_min_[min_index]->min_rank = active_index;
|
||||
if (++min_index < size_) {
|
||||
min = sorted_by_min_[min_index]->min_value;
|
||||
}
|
||||
} else {
|
||||
if (max != last) {
|
||||
bounds_[++active_index] = max;
|
||||
last = max;
|
||||
}
|
||||
sorted_by_max_[j]->max_rank = active_index;
|
||||
if (++j == size_) {
|
||||
sorted_by_max_[max_index]->max_rank = active_index;
|
||||
if (++max_index == size_) {
|
||||
break;
|
||||
}
|
||||
max = sorted_by_max_[j]->max_value + 1;
|
||||
max = sorted_by_max_[max_index]->max_value + 1;
|
||||
}
|
||||
}
|
||||
active_size_ = active_index;
|
||||
@@ -477,7 +477,7 @@ class GccConstraint : public Constraint {
|
||||
solver()->Fail();
|
||||
}
|
||||
if (hall_[x] > x) {
|
||||
int64 w = PathMax(hall_, hall_[x]);
|
||||
const int64 w = PathMax(hall_, hall_[x]);
|
||||
sorted_by_max_[i]->min_value = bounds_[w];
|
||||
PathSet(&hall_, x, w, w);
|
||||
changed = true;
|
||||
|
||||
@@ -2870,7 +2870,7 @@ Decision* FindOneNeighbor::Next(Solver* const solver) {
|
||||
solver->filtered_neighbors_ += 1;
|
||||
assignment_copy->Copy(reference_assignment_.get());
|
||||
assignment_copy->Copy(delta);
|
||||
if (solver->NestedSolve(restore, false)) {
|
||||
if (solver->SolveAndCommit(restore)) {
|
||||
solver->accepted_neighbors_ += 1;
|
||||
assignment_->Store();
|
||||
neighbor_found_ = true;
|
||||
@@ -3081,11 +3081,18 @@ NestedSolveDecision::NestedSolveDecision(DecisionBuilder* const db,
|
||||
|
||||
void NestedSolveDecision::Apply(Solver* const solver) {
|
||||
CHECK(NULL != solver);
|
||||
if (solver->NestedSolve(db_, restore_,
|
||||
monitors_.data(), monitors_.size())) {
|
||||
solver->SaveAndSetValue(&state_, static_cast<int>(DECISION_FOUND));
|
||||
if (restore_) {
|
||||
if (solver->Solve(db_, monitors_.data(), monitors_.size())) {
|
||||
solver->SaveAndSetValue(&state_, static_cast<int>(DECISION_FOUND));
|
||||
} else {
|
||||
solver->SaveAndSetValue(&state_, static_cast<int>(DECISION_FAILED));
|
||||
}
|
||||
} else {
|
||||
solver->SaveAndSetValue(&state_, static_cast<int>(DECISION_FAILED));
|
||||
if (solver->SolveAndCommit(db_, monitors_.data(), monitors_.size())) {
|
||||
solver->SaveAndSetValue(&state_, static_cast<int>(DECISION_FOUND));
|
||||
} else {
|
||||
solver->SaveAndSetValue(&state_, static_cast<int>(DECISION_FAILED));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -133,6 +133,7 @@ class MtSolveSupport : public ParallelSolveSupport {
|
||||
void LockMutex();
|
||||
// Unlocks the internal mutex.
|
||||
void UnlockMutex();
|
||||
|
||||
private:
|
||||
bool CheckTermination();
|
||||
void Reset();
|
||||
|
||||
@@ -4138,7 +4138,7 @@ class SolveOnce : public DecisionBuilder {
|
||||
virtual ~SolveOnce() {}
|
||||
|
||||
virtual Decision* Next(Solver* s) {
|
||||
bool res = s->NestedSolve(db_, false, monitors_);
|
||||
bool res = s->SolveAndCommit(db_, monitors_);
|
||||
if (!res) {
|
||||
s->Fail();
|
||||
}
|
||||
@@ -4255,7 +4255,7 @@ class NestedOptimize : public DecisionBuilder {
|
||||
}
|
||||
|
||||
virtual Decision* Next(Solver* solver) {
|
||||
solver->NestedSolve(db_, true, monitors_);
|
||||
solver->Solve(db_, monitors_);
|
||||
if (collector_->solution_count() == 0) {
|
||||
solver->Fail();
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user