00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014 #include <string.h>
00015 #include <algorithm>
00016 #include "base/hash.h"
00017 #include <list>
00018 #include <string>
00019 #include <utility>
00020 #include <vector>
00021
00022 #include "base/callback.h"
00023 #include "base/casts.h"
00024 #include "base/commandlineflags.h"
00025 #include "base/integral_types.h"
00026 #include "base/logging.h"
00027 #include "base/macros.h"
00028 #include "base/scoped_ptr.h"
00029 #include "base/stringprintf.h"
00030 #include "base/timer.h"
00031 #include "base/join.h"
00032 #include "base/bitmap.h"
00033 #include "base/concise_iterator.h"
00034 #include "base/map-util.h"
00035 #include "base/stl_util.h"
00036 #include "base/hash.h"
00037 #include "constraint_solver/constraint_solver.h"
00038 #include "constraint_solver/constraint_solveri.h"
00039 #include "constraint_solver/search_limit.pb.h"
00040 #include "util/string_array.h"
00041 #include "base/random.h"
00042
00043 DEFINE_bool(cp_use_sparse_gls_penalties, false,
00044 "Use sparse implementation to store Guided Local Search penalties");
00045
00046 namespace operations_research {
00047
00048
00049
00050 SearchLog::SearchLog(Solver* const s,
00051 OptimizeVar* const obj,
00052 IntVar* const var,
00053 ResultCallback<string>* display_callback,
00054 int period)
00055 : SearchMonitor(s),
00056 period_(period),
00057 timer_(new WallTimer),
00058 var_(var),
00059 obj_(obj),
00060 display_callback_(display_callback),
00061 nsol_(0),
00062 tick_(0LL),
00063 objective_min_(kint64max),
00064 objective_max_(kint64min),
00065 min_right_depth_(kint32max),
00066 max_depth_(0),
00067 sliding_min_depth_(0),
00068 sliding_max_depth_(0) {
00069 CHECK(obj == NULL || var == NULL) << "Either var or obj need to be NULL.";
00070 if (display_callback_ != NULL) {
00071 display_callback_->CheckIsRepeatable();
00072 }
00073 }
00074
00075 SearchLog::~SearchLog() {}
00076
00077 void SearchLog::EnterSearch() {
00078 const string buffer = StringPrintf("Start search, %s", MemoryUsage().c_str());
00079 OutputLine(buffer);
00080 timer_->Restart();
00081 min_right_depth_ = kint32max;
00082 }
00083
00084 void SearchLog::ExitSearch() {
00085 const int64 branches = solver()->branches();
00086 int64 ms = timer_->GetInMs();
00087 if (ms == 0) {
00088 ms = 1;
00089 }
00090 const string buffer = StringPrintf(
00091 "End search (time = %" GG_LL_FORMAT "d ms, branches = %"
00092 GG_LL_FORMAT "d, failures = %" GG_LL_FORMAT
00093 "d, %s, speed = %" GG_LL_FORMAT "d branches/s)",
00094 ms, branches, solver()->failures(),
00095 MemoryUsage().c_str(), branches * 1000 / ms);
00096 OutputLine(buffer);
00097 }
00098
00099 bool SearchLog::AtSolution() {
00100 Maintain();
00101 const int depth = solver()->SearchDepth();
00102 string obj_str = "";
00103 int64 current = 0;
00104 bool objective_updated = false;
00105 if (obj_ != NULL) {
00106 current = obj_->Var()->Value();
00107 obj_str = obj_->Print();
00108 objective_updated = true;
00109 } else if (var_!= NULL) {
00110 current = var_->Value();
00111 StringAppendF(&obj_str, "%" GG_LL_FORMAT "d, ", current);
00112 objective_updated = true;
00113 }
00114 if (objective_updated) {
00115 if (current >= objective_min_) {
00116 StringAppendF(&obj_str,
00117 "objective minimum = %" GG_LL_FORMAT "d, ",
00118 objective_min_);
00119 } else {
00120 objective_min_ = current;
00121 }
00122 if (current <= objective_max_) {
00123 StringAppendF(&obj_str,
00124 "objective maximum = %" GG_LL_FORMAT "d, ",
00125 objective_max_);
00126 } else {
00127 objective_max_ = current;
00128 }
00129 }
00130 string log;
00131 StringAppendF(&log,
00132 "Solution #%d (%stime = %" GG_LL_FORMAT
00133 "d ms, branches = %" GG_LL_FORMAT "d,"
00134 " failures = %" GG_LL_FORMAT "d, depth = %d",
00135 nsol_++, obj_str.c_str(), timer_->GetInMs(),
00136 solver()->branches(),
00137 solver()->failures(),
00138 depth);
00139 if (solver()->neighbors() != 0) {
00140 StringAppendF(&log,
00141 ", neighbors = %" GG_LL_FORMAT
00142 "d, filtered neighbors = %" GG_LL_FORMAT "d,"
00143 " accepted neighbors = %" GG_LL_FORMAT "d",
00144 solver()->neighbors(),
00145 solver()->filtered_neighbors(),
00146 solver()->accepted_neighbors());
00147 }
00148 StringAppendF(&log, ", %s)", MemoryUsage().c_str());
00149 const int progress = solver()->TopProgressPercent();
00150 if (progress != SearchMonitor::kNoProgress) {
00151 StringAppendF(&log, ", limit = %d%%", progress);
00152 }
00153 LG << log;
00154 if (display_callback_.get() != NULL) {
00155 LG << display_callback_->Run();
00156 }
00157 return false;
00158 }
00159
00160 void SearchLog::BeginFail() {
00161 Maintain();
00162 }
00163
00164 void SearchLog::NoMoreSolutions() {
00165 string buffer = StringPrintf(
00166 "Finished search tree, time = %" GG_LL_FORMAT
00167 "d ms, branches = %" GG_LL_FORMAT "d,"
00168 " failures = %" GG_LL_FORMAT "d",
00169 timer_->GetInMs(),
00170 solver()->branches(),
00171 solver()->failures());
00172 if (solver()->neighbors() != 0) {
00173 StringAppendF(&buffer,
00174 ", neighbors = %" GG_LL_FORMAT
00175 "d, filtered neighbors = %" GG_LL_FORMAT "d,"
00176 " accepted neigbors = %" GG_LL_FORMAT "d",
00177 solver()->neighbors(),
00178 solver()->filtered_neighbors(),
00179 solver()->accepted_neighbors());
00180 }
00181 StringAppendF(&buffer, ", %s)", MemoryUsage().c_str());
00182 OutputLine(buffer);
00183 }
00184
00185 void SearchLog::ApplyDecision(Decision* const d) {
00186 Maintain();
00187 const int64 b = solver()->branches();
00188 if (b % period_ == 0 && b > 0) {
00189 OutputDecision();
00190 }
00191 }
00192
00193 void SearchLog::RefuteDecision(Decision* const d) {
00194 min_right_depth_ = std::min(min_right_depth_, solver()->SearchDepth());
00195 ApplyDecision(d);
00196 }
00197
00198 void SearchLog::OutputDecision() {
00199 string buffer = StringPrintf(
00200 "%" GG_LL_FORMAT "d branches, %" GG_LL_FORMAT "d ms, %"
00201 GG_LL_FORMAT "d failures",
00202 solver()->branches(), timer_->GetInMs(), solver()->failures());
00203 if (min_right_depth_ != kint32max && max_depth_ != 0) {
00204 const int depth = solver()->SearchDepth();
00205 StringAppendF(
00206 &buffer, ", tree pos=%d/%d/%d minref=%d max=%d",
00207 sliding_min_depth_, depth, sliding_max_depth_,
00208 min_right_depth_, max_depth_);
00209 sliding_min_depth_ = depth;
00210 sliding_max_depth_ = depth;
00211 }
00212 if (obj_ != NULL
00213 && objective_min_ != kint64max
00214 && objective_max_ != kint64min) {
00215 StringAppendF(&buffer,
00216 ", objective minimum = %" GG_LL_FORMAT "d"
00217 ", objective maximum = %" GG_LL_FORMAT "d",
00218 objective_min_, objective_max_);
00219 }
00220 const int progress = solver()->TopProgressPercent();
00221 if (progress != SearchMonitor::kNoProgress) {
00222 StringAppendF(&buffer, ", limit = %d%%", progress);
00223 }
00224 OutputLine(buffer);
00225 }
00226
00227 void SearchLog::Maintain() {
00228 const int current_depth = solver()->SearchDepth();
00229 sliding_min_depth_ = std::min(current_depth, sliding_min_depth_);
00230 sliding_max_depth_ = std::max(current_depth, sliding_max_depth_);
00231 max_depth_ = std::max(current_depth, max_depth_);
00232 }
00233
00234 void SearchLog::BeginInitialPropagation() {
00235 tick_ = timer_->GetInMs();
00236 }
00237
00238 void SearchLog::EndInitialPropagation() {
00239 const int64 delta = std::max(timer_->GetInMs() - tick_, 0LL);
00240 const string buffer = StringPrintf(
00241 "Root node processed (time = %" GG_LL_FORMAT
00242 "d ms, constraints = %d, %s)",
00243 delta, solver()->constraints(), MemoryUsage().c_str());
00244 OutputLine(buffer);
00245 }
00246
00247 void SearchLog::OutputLine(const string& line) {
00248 LG << line;
00249 }
00250
00251 string SearchLog::MemoryUsage() {
00252 static const int64 kDisplayThreshold = 2;
00253 static const int64 kKiloByte = 1024;
00254 static const int64 kMegaByte = kKiloByte * kKiloByte;
00255 static const int64 kGigaByte = kMegaByte * kKiloByte;
00256 const int64 memory_usage = Solver::MemoryUsage();
00257 if (memory_usage > kDisplayThreshold * kGigaByte) {
00258 return StringPrintf("memory used = %.2lf GB",
00259 memory_usage * 1.0 / kGigaByte);
00260 } else if (memory_usage > kDisplayThreshold * kMegaByte) {
00261 return StringPrintf("memory used = %.2lf MB",
00262 memory_usage * 1.0 / kMegaByte);
00263 } else if (memory_usage > kDisplayThreshold * kKiloByte) {
00264 return StringPrintf("memory used = %2lf KB",
00265 memory_usage * 1.0 / kKiloByte);
00266 } else {
00267 return StringPrintf("memory used = %" GG_LL_FORMAT "d", memory_usage);
00268 }
00269 }
00270
00271 SearchMonitor* Solver::MakeSearchLog(int period) {
00272 return RevAlloc(new SearchLog(this, NULL, NULL, NULL, period));
00273 }
00274
00275 SearchMonitor* Solver::MakeSearchLog(int period, IntVar* const var) {
00276 return RevAlloc(new SearchLog(this, NULL, var, NULL, period));
00277 }
00278
00279 SearchMonitor* Solver::MakeSearchLog(int period,
00280 ResultCallback<string>* display_callback) {
00281 return RevAlloc(new SearchLog(this, NULL, NULL, display_callback, period));
00282 }
00283
00284 SearchMonitor* Solver::MakeSearchLog(int period, IntVar* const var,
00285 ResultCallback<string>* display_callback) {
00286 return RevAlloc(new SearchLog(this, NULL, var, display_callback, period));
00287 }
00288
00289 SearchMonitor* Solver::MakeSearchLog(int period, OptimizeVar* const obj) {
00290 return RevAlloc(new SearchLog(this, obj, NULL, NULL, period));
00291 }
00292
00293 SearchMonitor* Solver::MakeSearchLog(int period, OptimizeVar* const obj,
00294 ResultCallback<string>* display_callback) {
00295 return RevAlloc(new SearchLog(this, obj, NULL, display_callback, period));
00296 }
00297
00298
00299
00300 namespace {
00301 class SearchTrace : public SearchMonitor {
00302 public:
00303 SearchTrace(Solver* const s, const string& prefix)
00304 : SearchMonitor(s), prefix_(prefix) {}
00305 virtual ~SearchTrace() {}
00306
00307 virtual void EnterSearch() {
00308 LG << prefix_ << " EnterSearch(" << solver()->SolveDepth() << ")";
00309 }
00310 virtual void RestartSearch() {
00311 LG << prefix_ << " RestartSearch(" << solver()->SolveDepth() << ")";
00312 }
00313 virtual void ExitSearch() {
00314 LG << prefix_ << " ExitSearch(" << solver()->SolveDepth() << ")";
00315 }
00316 virtual void BeginNextDecision(DecisionBuilder* const b) {
00317 LG << prefix_ << " BeginNextDecision(" << b << ") ";
00318 }
00319 virtual void EndNextDecision(DecisionBuilder* const b, Decision* const d) {
00320 if (d) {
00321 LG << prefix_ << " EndNextDecision(" << b << ", " << d << ") ";
00322 } else {
00323 LG << prefix_ << " EndNextDecision(" << b << ") ";
00324 }
00325 }
00326 virtual void ApplyDecision(Decision* const d) {
00327 LG << prefix_ << " ApplyDecision(" << d << ") ";
00328 }
00329 virtual void RefuteDecision(Decision* const d) {
00330 LG << prefix_ << " RefuteDecision(" << d << ") ";
00331 }
00332 virtual void AfterDecision(Decision* const d, bool apply) {
00333 LG << prefix_ << " AfterDecision(" << d << ", " << apply << ") ";
00334 }
00335 virtual void BeginFail() {
00336 LG << prefix_ << " BeginFail(" << solver()->SearchDepth() << ")";
00337 }
00338 virtual void EndFail() {
00339 LG << prefix_ << " EndFail(" << solver()->SearchDepth() << ")";
00340 }
00341 virtual void BeginInitialPropagation() {
00342 LG << prefix_ << " BeginInitialPropagation()";
00343 }
00344 virtual void EndInitialPropagation() {
00345 LG << prefix_ << " EndInitialPropagation()";
00346 }
00347 virtual bool AtSolution() {
00348 LG << prefix_ << " AtSolution()";
00349 return false;
00350 }
00351 virtual bool AcceptSolution() {
00352 LG << prefix_ << " AcceptSolution()";
00353 return true;
00354 }
00355 virtual void NoMoreSolutions() {
00356 LG << prefix_ << " NoMoreSolutions()";
00357 }
00358
00359 private:
00360 const string prefix_;
00361 };
00362 }
00363
00364 SearchMonitor* Solver::MakeSearchTrace(const string& prefix) {
00365 return RevAlloc(new SearchTrace(this, prefix));
00366 }
00367
00368
00369
00370 namespace {
00371 class CompositeDecisionBuilder : public DecisionBuilder {
00372 public:
00373 CompositeDecisionBuilder();
00374 explicit CompositeDecisionBuilder(const std::vector<DecisionBuilder*>& dbs);
00375 virtual ~CompositeDecisionBuilder();
00376 void Add(DecisionBuilder* const db);
00377 virtual void AppendMonitors(Solver* const solver,
00378 std::vector<SearchMonitor*>* const monitors);
00379 virtual void Accept(ModelVisitor* const visitor) const;
00380
00381 protected:
00382 std::vector<DecisionBuilder*> builders_;
00383 };
00384
00385 CompositeDecisionBuilder::CompositeDecisionBuilder() {}
00386
00387 CompositeDecisionBuilder::CompositeDecisionBuilder(
00388 const std::vector<DecisionBuilder*>& dbs) {
00389 for (int i = 0; i < dbs.size(); ++i) {
00390 Add(dbs[i]);
00391 }
00392 }
00393
00394 CompositeDecisionBuilder::~CompositeDecisionBuilder() {}
00395
00396 void CompositeDecisionBuilder::Add(DecisionBuilder* const db) {
00397 if (db != NULL) {
00398 builders_.push_back(db);
00399 }
00400 }
00401
00402 void CompositeDecisionBuilder::AppendMonitors(
00403 Solver* const solver,
00404 std::vector<SearchMonitor*>* const monitors) {
00405 for (ConstIter<std::vector<DecisionBuilder*> > it(builders_);
00406 !it.at_end();
00407 ++it) {
00408 (*it)->AppendMonitors(solver, monitors);
00409 }
00410 }
00411
00412 void CompositeDecisionBuilder::Accept(ModelVisitor* const visitor) const {
00413 for (ConstIter<std::vector<DecisionBuilder*> > it(builders_);
00414 !it.at_end();
00415 ++it) {
00416 (*it)->Accept(visitor);
00417 }
00418 }
00419 }
00420
00421
00422
00423 namespace {
00424 class ComposeDecisionBuilder : public CompositeDecisionBuilder {
00425 public:
00426 ComposeDecisionBuilder();
00427 explicit ComposeDecisionBuilder(const std::vector<DecisionBuilder*>& dbs);
00428 ~ComposeDecisionBuilder();
00429 virtual Decision* Next(Solver* const s);
00430 virtual string DebugString() const;
00431
00432 private:
00433 int start_index_;
00434 };
00435
00436 ComposeDecisionBuilder::ComposeDecisionBuilder() : start_index_(0) {}
00437
00438 ComposeDecisionBuilder::ComposeDecisionBuilder(
00439 const std::vector<DecisionBuilder*>& dbs)
00440 : CompositeDecisionBuilder(dbs), start_index_(0) {}
00441
00442 ComposeDecisionBuilder::~ComposeDecisionBuilder() {}
00443
00444 Decision* ComposeDecisionBuilder::Next(Solver* const s) {
00445 const int size = builders_.size();
00446 for (int i = start_index_; i < size; ++i) {
00447 Decision* d = builders_[i]->Next(s);
00448 if (d != NULL) {
00449 s->SaveAndSetValue(&start_index_, i);
00450 return d;
00451 }
00452 }
00453 s->SaveAndSetValue(&start_index_, size);
00454 return NULL;
00455 }
00456
00457 string ComposeDecisionBuilder::DebugString() const {
00458 return StringPrintf(
00459 "ComposeDecisionBuilder(%s)",
00460 DebugStringArray(builders_.data(), builders_.size(), ", ").c_str());
00461 }
00462 }
00463
00464 DecisionBuilder* Solver::Compose(DecisionBuilder* const db1,
00465 DecisionBuilder* const db2) {
00466 ComposeDecisionBuilder* c = RevAlloc(new ComposeDecisionBuilder());
00467 c->Add(db1);
00468 c->Add(db2);
00469 return c;
00470 }
00471
00472 DecisionBuilder* Solver::Compose(DecisionBuilder* const db1,
00473 DecisionBuilder* const db2,
00474 DecisionBuilder* const db3) {
00475 ComposeDecisionBuilder* c = RevAlloc(new ComposeDecisionBuilder());
00476 c->Add(db1);
00477 c->Add(db2);
00478 c->Add(db3);
00479 return c;
00480 }
00481
00482 DecisionBuilder* Solver::Compose(DecisionBuilder* const db1,
00483 DecisionBuilder* const db2,
00484 DecisionBuilder* const db3,
00485 DecisionBuilder* const db4) {
00486 ComposeDecisionBuilder* c = RevAlloc(new ComposeDecisionBuilder());
00487 c->Add(db1);
00488 c->Add(db2);
00489 c->Add(db3);
00490 c->Add(db4);
00491 return c;
00492 }
00493
00494 DecisionBuilder* Solver::Compose(const std::vector<DecisionBuilder*>& dbs) {
00495 return RevAlloc(new ComposeDecisionBuilder(dbs));
00496 }
00497
00498
00499
00500 namespace {
00501
00502 class TryDecisionBuilder;
00503
00504 class TryDecision : public Decision {
00505 public:
00506 explicit TryDecision(TryDecisionBuilder* const try_builder);
00507 virtual ~TryDecision();
00508 virtual void Apply(Solver* const solver);
00509 virtual void Refute(Solver* const solver);
00510 virtual string DebugString() const {
00511 return "TryDecision";
00512 }
00513
00514 private:
00515 TryDecisionBuilder* const try_builder_;
00516 };
00517
00518 class TryDecisionBuilder : public CompositeDecisionBuilder {
00519 public:
00520 TryDecisionBuilder();
00521 explicit TryDecisionBuilder(const std::vector<DecisionBuilder*>& dbs);
00522 virtual ~TryDecisionBuilder();
00523 virtual Decision* Next(Solver* const s);
00524 virtual string DebugString() const;
00525 void AdvanceToNextBuilder(Solver* const solver);
00526
00527 private:
00528 TryDecision try_decision_;
00529 int current_builder_;
00530 bool start_new_builder_;
00531 };
00532
00533 TryDecision::TryDecision(TryDecisionBuilder* const try_builder)
00534 : try_builder_(try_builder) {}
00535
00536 TryDecision::~TryDecision() {}
00537
00538 void TryDecision::Apply(Solver* const solver) {}
00539
00540 void TryDecision::Refute(Solver* const solver) {
00541 try_builder_->AdvanceToNextBuilder(solver);
00542 }
00543
00544 TryDecisionBuilder::TryDecisionBuilder()
00545 : CompositeDecisionBuilder(),
00546 try_decision_(this),
00547 current_builder_(-1),
00548 start_new_builder_(true) {}
00549
00550 TryDecisionBuilder::TryDecisionBuilder(const std::vector<DecisionBuilder*>& dbs)
00551 : CompositeDecisionBuilder(dbs),
00552 try_decision_(this),
00553 current_builder_(-1),
00554 start_new_builder_(true) {}
00555
00556 TryDecisionBuilder::~TryDecisionBuilder() {}
00557
00558 Decision* TryDecisionBuilder::Next(Solver* const solver) {
00559 if (current_builder_ < 0) {
00560 solver->SaveAndSetValue(¤t_builder_, 0);
00561 start_new_builder_ = true;
00562 }
00563 if (start_new_builder_) {
00564 start_new_builder_ = false;
00565 return &try_decision_;
00566 } else {
00567 return builders_[current_builder_]->Next(solver);
00568 }
00569 }
00570
00571 string TryDecisionBuilder::DebugString() const {
00572 return StringPrintf(
00573 "TryDecisionBuilder(%s)",
00574 DebugStringArray(builders_.data(), builders_.size(), ", ").c_str());
00575 }
00576
00577 void TryDecisionBuilder::AdvanceToNextBuilder(Solver* const solver) {
00578 ++current_builder_;
00579 start_new_builder_ = true;
00580 if (current_builder_ >= builders_.size()) {
00581 solver->Fail();
00582 }
00583 }
00584
00585 }
00586
00587 DecisionBuilder* Solver::Try(DecisionBuilder* const db1,
00588 DecisionBuilder* const db2) {
00589 TryDecisionBuilder* try_db = RevAlloc(new TryDecisionBuilder());
00590 try_db->Add(db1);
00591 try_db->Add(db2);
00592 return try_db;
00593 }
00594
00595 DecisionBuilder* Solver::Try(DecisionBuilder* const db1,
00596 DecisionBuilder* const db2,
00597 DecisionBuilder* const db3) {
00598 TryDecisionBuilder* try_db = RevAlloc(new TryDecisionBuilder());
00599 try_db->Add(db1);
00600 try_db->Add(db2);
00601 try_db->Add(db3);
00602 return try_db;
00603 }
00604
00605 DecisionBuilder* Solver::Try(DecisionBuilder* const db1,
00606 DecisionBuilder* const db2,
00607 DecisionBuilder* const db3,
00608 DecisionBuilder* const db4) {
00609 TryDecisionBuilder* try_db = RevAlloc(new TryDecisionBuilder());
00610 try_db->Add(db1);
00611 try_db->Add(db2);
00612 try_db->Add(db3);
00613 try_db->Add(db4);
00614 return try_db;
00615 }
00616
00617 DecisionBuilder* Solver::Try(const std::vector<DecisionBuilder*>& dbs) {
00618 return RevAlloc(new TryDecisionBuilder(dbs));
00619 }
00620
00621
00622
00623
00624
00625 namespace {
00626 class BaseVariableAssignmentSelector : public BaseObject {
00627 public:
00628 BaseVariableAssignmentSelector() {}
00629 virtual ~BaseVariableAssignmentSelector() {}
00630 virtual int64 SelectValue(const IntVar* const v, int64 id) = 0;
00631 virtual IntVar* SelectVariable(Solver* const s, int64* id) = 0;
00632 virtual void Accept(ModelVisitor* const visitor) const = 0;
00633 };
00634
00635
00636
00637 class VariableSelector : public BaseObject {
00638 public:
00639 VariableSelector(const IntVar* const* vars, int size)
00640 : vars_(NULL), size_(size) {
00641 CHECK_GE(size_, 0);
00642 if (size_ > 0) {
00643 vars_.reset(new IntVar*[size_]);
00644 memcpy(vars_.get(), vars, size_ * sizeof(*vars));
00645 }
00646 }
00647 virtual ~VariableSelector() {}
00648 virtual IntVar* Select(Solver* const s, int64* id) = 0;
00649 string VarDebugString() const;
00650 void Accept(ModelVisitor* const visitor) const {
00651 visitor->BeginVisitExtension(ModelVisitor::kVariableGroupExtension);
00652 visitor->VisitIntegerVariableArrayArgument(ModelVisitor::kVarsArgument,
00653 vars_.get(),
00654 size_);
00655 visitor->EndVisitExtension(ModelVisitor::kVariableGroupExtension);
00656 }
00657
00658 protected:
00659 scoped_array<IntVar*> vars_;
00660 int size_;
00661 };
00662
00663 string VariableSelector::VarDebugString() const {
00664 string out = "(";
00665 out.append(DebugStringArray(vars_.get(), size_, ", "));
00666 out.append(")");
00667 return out;
00668 }
00669
00670
00671
00672 class FirstUnboundSelector : public VariableSelector {
00673 public:
00674 FirstUnboundSelector(const IntVar* const* vars, int size)
00675 : VariableSelector(vars, size), first_(0) {}
00676 virtual ~FirstUnboundSelector() {}
00677 virtual IntVar* Select(Solver* const s, int64* id);
00678 virtual string DebugString() const { return "ChooseFirstUnbound"; }
00679
00680 private:
00681 int first_;
00682 };
00683
00684 IntVar* FirstUnboundSelector::Select(Solver* const s, int64* id) {
00685 for (int i = first_; i < size_; ++i) {
00686 IntVar* const var = vars_[i];
00687 if (!var->Bound()) {
00688 s->SaveAndSetValue(&first_, i);
00689 *id = i;
00690 return var;
00691 }
00692 }
00693 s->SaveAndSetValue(&first_, size_);
00694 *id = size_;
00695 return NULL;
00696 }
00697
00698
00699
00700 class MinSizeLowestMinSelector : public VariableSelector {
00701 public:
00702 MinSizeLowestMinSelector(const IntVar* const* vars, int size)
00703 : VariableSelector(vars, size) {}
00704 virtual ~MinSizeLowestMinSelector() {}
00705 virtual IntVar* Select(Solver* const s, int64* id);
00706 virtual string DebugString() const { return "MinSizeLowestMinSelector"; }
00707 };
00708
00709 IntVar* MinSizeLowestMinSelector::Select(Solver* const s, int64* id) {
00710 IntVar* result = NULL;
00711 int64 best_size = kint64max;
00712 int64 best_min = kint64max;
00713 int index = -1;
00714 for (int i = 0; i < size_; ++i) {
00715 IntVar* const var = vars_[i];
00716 if (!var->Bound()) {
00717 if (var->Size() < best_size ||
00718 (var->Size() == best_size && var->Min() < best_min)) {
00719 best_size = var->Size();
00720 best_min = var->Min();
00721 index = i;
00722 result = var;
00723 }
00724 }
00725 }
00726 if (index == -1) {
00727 *id = size_;
00728 return NULL;
00729 } else {
00730 *id = index;
00731 return result;
00732 }
00733 }
00734
00735
00736
00737 class MinSizeHighestMinSelector : public VariableSelector {
00738 public:
00739 MinSizeHighestMinSelector(const IntVar* const* vars, int size)
00740 : VariableSelector(vars, size) {}
00741 virtual ~MinSizeHighestMinSelector() {}
00742 virtual IntVar* Select(Solver* const s, int64* id);
00743 virtual string DebugString() const { return "MinSizeHighestMinSelector"; }
00744 };
00745
00746 IntVar* MinSizeHighestMinSelector::Select(Solver* const s, int64* id) {
00747 IntVar* result = NULL;
00748 int64 best_size = kint64max;
00749 int64 best_min = kint64min;
00750 int index = -1;
00751 for (int i = 0; i < size_; ++i) {
00752 IntVar* const var = vars_[i];
00753 if (!var->Bound()) {
00754 if (var->Size() < best_size ||
00755 (var->Size() == best_size && var->Min() > best_min)) {
00756 best_size = var->Size();
00757 best_min = var->Min();
00758 index = i;
00759 result = var;
00760 }
00761 }
00762 }
00763 if (index == -1) {
00764 *id = size_;
00765 return NULL;
00766 } else {
00767 *id = index;
00768 return result;
00769 }
00770 }
00771
00772
00773
00774 class MinSizeLowestMaxSelector : public VariableSelector {
00775 public:
00776 MinSizeLowestMaxSelector(const IntVar* const* vars, int size)
00777 : VariableSelector(vars, size) {}
00778 virtual ~MinSizeLowestMaxSelector() {}
00779 virtual IntVar* Select(Solver* const s, int64* id);
00780 virtual string DebugString() const { return "MinSizeLowestMaxSelector"; }
00781 };
00782
00783 IntVar* MinSizeLowestMaxSelector::Select(Solver* const s, int64* id) {
00784 IntVar* result = NULL;
00785 int64 best_size = kint64max;
00786 int64 best_max = kint64max;
00787 int index = -1;
00788 for (int i = 0; i < size_; ++i) {
00789 IntVar* const var = vars_[i];
00790 if (!var->Bound()) {
00791 if (var->Size() < best_size ||
00792 (var->Size() == best_size && var->Max() < best_max)) {
00793 best_size = var->Size();
00794 best_max = var->Max();
00795 index = i;
00796 result = var;
00797 }
00798 }
00799 }
00800 if (index == -1) {
00801 *id = size_;
00802 return NULL;
00803 } else {
00804 *id = index;
00805 return result;
00806 }
00807 }
00808
00809
00810
00811 class MinSizeHighestMaxSelector : public VariableSelector {
00812 public:
00813 MinSizeHighestMaxSelector(const IntVar* const* vars, int size)
00814 : VariableSelector(vars, size) {}
00815 virtual ~MinSizeHighestMaxSelector() {}
00816 virtual IntVar* Select(Solver* const s, int64* id);
00817 virtual string DebugString() const { return "MinSizeHighestMaxSelector"; }
00818 };
00819
00820 IntVar* MinSizeHighestMaxSelector::Select(Solver* const s, int64* id) {
00821 IntVar* result = NULL;
00822 int64 best_size = kint64max;
00823 int64 best_max = kint64min;
00824 int index = -1;
00825 for (int i = 0; i < size_; ++i) {
00826 IntVar* const var = vars_[i];
00827 if (!var->Bound()) {
00828 if (var->Size() < best_size ||
00829 (var->Size() == best_size && var->Max() > best_max)) {
00830 best_size = var->Size();
00831 best_max = var->Max();
00832 index = i;
00833 result = var;
00834 }
00835 }
00836 }
00837 if (index == -1) {
00838 *id = size_;
00839 return NULL;
00840 } else {
00841 *id = index;
00842 return result;
00843 }
00844 }
00845
00846
00847
00848 class RandomSelector : public VariableSelector {
00849 public:
00850 RandomSelector(const IntVar* const* vars, int size)
00851 : VariableSelector(vars, size) {}
00852 virtual ~RandomSelector() {}
00853 virtual IntVar* Select(Solver* const s, int64* id);
00854 virtual string DebugString() const { return "RandomSelector"; }
00855 };
00856
00857 IntVar* RandomSelector::Select(Solver* const s, int64* id) {
00858 const int shift = s->Rand32(size_);
00859 for (int i = 0; i < size_; ++i) {
00860 const int index = (i + shift) % size_;
00861 IntVar* const var = vars_[index];
00862 if (!var->Bound()) {
00863 *id = index;
00864 return var;
00865 }
00866 }
00867 *id = size_;
00868 return NULL;
00869 }
00870
00871
00872
00873 class CheapestVarSelector : public VariableSelector {
00874 public:
00875 CheapestVarSelector(const IntVar* const* vars,
00876 int size,
00877 ResultCallback1<int64, int64>* var_eval)
00878 : VariableSelector(vars, size), var_evaluator_(var_eval) {}
00879 virtual ~CheapestVarSelector() {}
00880 virtual IntVar* Select(Solver* const s, int64* id);
00881 virtual string DebugString() const { return "CheapestVarSelector"; }
00882
00883 private:
00884 scoped_ptr<ResultCallback1<int64, int64> > var_evaluator_;
00885 };
00886
00887 IntVar* CheapestVarSelector::Select(Solver* const s, int64* id) {
00888 IntVar* result = NULL;
00889 int64 best_eval = kint64max;
00890 int index = -1;
00891 for (int i = 0; i < size_; ++i) {
00892 IntVar* const var = vars_[i];
00893 if (!var->Bound()) {
00894 const int64 eval = var_evaluator_->Run(i);
00895 if (eval < best_eval) {
00896 best_eval = eval;
00897 index = i;
00898 result = var;
00899 }
00900 }
00901 }
00902 if (index == -1) {
00903 *id = size_;
00904 return NULL;
00905 } else {
00906 *id = index;
00907 return result;
00908 }
00909 }
00910
00911
00912
00913
00914 class PathSelector : public VariableSelector {
00915 public:
00916 PathSelector(const IntVar* const* vars, int size)
00917 : VariableSelector(vars, size), first_(kint64max) {}
00918 virtual ~PathSelector() {}
00919 virtual IntVar* Select(Solver* const s, int64* id);
00920 virtual string DebugString() const { return "ChooseNextOnPath"; }
00921
00922 private:
00923 bool UpdateIndex(int64* index) const;
00924 bool FindPathStart(int64* index) const;
00925
00926 int64 first_;
00927 };
00928
00929 IntVar* PathSelector::Select(Solver* const s, int64* id) {
00930 *id = first_;
00931 if (!UpdateIndex(id)) {
00932 return NULL;
00933 }
00934 int count = 0;
00935 while (vars_[*id]->Bound()) {
00936 *id = vars_[*id]->Value();
00937 if (!UpdateIndex(id)) {
00938 return NULL;
00939 }
00940 ++count;
00941 if (count >= size_ && !FindPathStart(id)) {
00942 return NULL;
00943 }
00944 }
00945 IntVar* const var = vars_[*id];
00946 s->SaveAndSetValue(&first_, *id);
00947 return var;
00948 }
00949
00950 bool PathSelector::UpdateIndex(int64* index) const {
00951 if (*index >= size_) {
00952 if (!FindPathStart(index)) {
00953 return false;
00954 }
00955 }
00956 return true;
00957 }
00958
00959
00960
00961
00962
00963
00964
00965 bool PathSelector::FindPathStart(int64* index) const {
00966
00967 for (int i = size_ - 1; i >= 0; --i) {
00968 if (vars_[i]->Bound()) {
00969 const int next = vars_[i]->Value();
00970 if (next < size_ && !vars_[next]->Bound()) {
00971 *index = next;
00972 return true;
00973 }
00974 }
00975 }
00976
00977 for (int i = size_ - 1; i >= 0; --i) {
00978 if (!vars_[i]->Bound()) {
00979 bool has_possible_prev = false;
00980 for (int j = 0; j < size_; ++j) {
00981 if (vars_[j]->Contains(i)) {
00982 has_possible_prev = true;
00983 break;
00984 }
00985 }
00986 if (!has_possible_prev) {
00987 *index = i;
00988 return true;
00989 }
00990 }
00991 }
00992
00993 for (int i = 0; i < size_; ++i) {
00994 if (!vars_[i]->Bound()) {
00995 *index = i;
00996 return true;
00997 }
00998 }
00999 return false;
01000 }
01001
01002
01003
01004 class ValueSelector : public BaseObject {
01005 public:
01006 ValueSelector() {}
01007 virtual ~ValueSelector() {}
01008 virtual int64 Select(const IntVar* const v, int64 id) = 0;
01009 };
01010
01011
01012
01013 class MinValueSelector : public ValueSelector {
01014 public:
01015 MinValueSelector() {}
01016 virtual ~MinValueSelector() {}
01017 virtual int64 Select(const IntVar* const v, int64 id) { return v->Min(); }
01018 string DebugString() const { return "AssignMin"; }
01019 };
01020
01021
01022
01023 class MaxValueSelector : public ValueSelector {
01024 public:
01025 MaxValueSelector() {}
01026 virtual ~MaxValueSelector() {}
01027 virtual int64 Select(const IntVar* const v, int64 id) { return v->Max(); }
01028 string DebugString() const { return "AssignMax"; }
01029 };
01030
01031
01032
01033 class RandomValueSelector : public ValueSelector {
01034 public:
01035 RandomValueSelector() {}
01036 virtual ~RandomValueSelector() {}
01037 virtual int64 Select(const IntVar* const v, int64 id);
01038 string DebugString() const { return "AssignRandom"; }
01039 };
01040
01041 int64 RandomValueSelector::Select(const IntVar* const v, int64 id) {
01042 const int64 span = v->Max() - v->Min() + 1;
01043 const int64 size = v->Size();
01044 Solver* const s = v->solver();
01045 if (size > span / 4) {
01046
01047 for (;;) {
01048 const int64 value = v->Min() + s->Rand64(span);
01049 if (v->Contains(value)) {
01050 return value;
01051 }
01052 }
01053 } else {
01054 int64 index = s->Rand64(size);
01055 if (index <= size / 2) {
01056 for (int64 i = v->Min(); i <= v->Max(); ++i) {
01057 if (v->Contains(i)) {
01058 if (--index == 0) {
01059 return i;
01060 }
01061 }
01062 }
01063 CHECK_LE(index, 0);
01064 } else {
01065 for (int64 i = v->Max(); i > v->Min(); --i) {
01066 if (v->Contains(i)) {
01067 if (--index == 0) {
01068 return i;
01069 }
01070 }
01071 }
01072 CHECK_LE(index, 0);
01073 }
01074 }
01075 return 0LL;
01076 }
01077
01078
01079
01080 class CenterValueSelector : public ValueSelector {
01081 public:
01082 CenterValueSelector() {}
01083 virtual ~CenterValueSelector() {}
01084 virtual int64 Select(const IntVar* const v, int64 id);
01085 string DebugString() const { return "AssignCenter"; }
01086 };
01087
01088 int64 CenterValueSelector::Select(const IntVar* const v, int64 id) {
01089 const int64 vmin = v->Min();
01090 const int64 vmax = v->Max();
01091 const int64 mid = (vmin + vmax) / 2;
01092 if (v->Contains(mid)) {
01093 return mid;
01094 }
01095 const int64 diameter = vmax - mid;
01096 for (int64 i = 1; i <= diameter; ++i) {
01097 if (v->Contains(mid + i)) {
01098 return mid + i;
01099 }
01100 if (v->Contains(mid - i)) {
01101 return mid - i;
01102 }
01103 }
01104 return 0LL;
01105 }
01106
01107
01108
01109 class CheapestValueSelector : public ValueSelector {
01110 public:
01111 CheapestValueSelector(ResultCallback2<int64, int64, int64>* eval,
01112 ResultCallback1<int64, int64>* tie_breaker)
01113 : eval_(eval), tie_breaker_(tie_breaker) {}
01114 virtual ~CheapestValueSelector() {}
01115 virtual int64 Select(const IntVar* const v, int64 id);
01116 string DebugString() const { return "CheapestValue"; }
01117
01118 private:
01119 scoped_ptr<ResultCallback2<int64, int64, int64> > eval_;
01120 scoped_ptr<ResultCallback1<int64, int64> > tie_breaker_;
01121 std::vector<int64> cache_;
01122 };
01123
01124 int64 CheapestValueSelector::Select(const IntVar* const v, int64 id) {
01125 cache_.clear();
01126 int64 best = kint64max;
01127 scoped_ptr<IntVarIterator> it(v->MakeDomainIterator(false));
01128 for (it->Init(); it->Ok(); it->Next()) {
01129 const int i = it->Value();
01130 int64 eval = eval_->Run(id, i);
01131 if (eval < best) {
01132 best = eval;
01133 cache_.clear();
01134 cache_.push_back(i);
01135 } else if (eval == best) {
01136 cache_.push_back(i);
01137 }
01138 }
01139 DCHECK_GT(cache_.size(), 0);
01140 if (tie_breaker_.get() == NULL || cache_.size() == 1) {
01141 return cache_.back();
01142 } else {
01143 return cache_[tie_breaker_->Run(cache_.size())];
01144 }
01145 }
01146
01147
01148
01149 class VariableAssignmentSelector : public BaseVariableAssignmentSelector {
01150 public:
01151 VariableAssignmentSelector(VariableSelector* const var_selector,
01152 ValueSelector* const value_selector)
01153 : var_selector_(var_selector), value_selector_(value_selector) {}
01154 virtual ~VariableAssignmentSelector() {}
01155 virtual int64 SelectValue(const IntVar* const var, int64 id) {
01156 return value_selector_->Select(var, id);
01157 }
01158 virtual IntVar* SelectVariable(Solver* const s, int64* id) {
01159 return var_selector_->Select(s, id);
01160 }
01161 string DebugString() const;
01162
01163 virtual void Accept(ModelVisitor* const visitor) const {
01164 var_selector_->Accept(visitor);
01165 }
01166
01167 private:
01168 VariableSelector* const var_selector_;
01169 ValueSelector* const value_selector_;
01170 };
01171
01172 string VariableAssignmentSelector::DebugString() const {
01173 return var_selector_->DebugString() + "_"
01174 + value_selector_->DebugString()
01175 + var_selector_->VarDebugString();
01176 }
01177
01178
01179
01180 class BaseEvaluatorSelector : public BaseVariableAssignmentSelector {
01181 public:
01182 BaseEvaluatorSelector(const IntVar* const* vars, int size,
01183 ResultCallback2<int64, int64, int64>* evaluator);
01184 ~BaseEvaluatorSelector() {}
01185
01186 virtual void Accept(ModelVisitor* const visitor) const {
01187 visitor->BeginVisitExtension(ModelVisitor::kVariableGroupExtension);
01188 visitor->VisitIntegerVariableArrayArgument(ModelVisitor::kVarsArgument,
01189 vars_.get(),
01190 size_);
01191 visitor->EndVisitExtension(ModelVisitor::kVariableGroupExtension);
01192 }
01193
01194 protected:
01195 struct Element {
01196 Element() : var(0), value(0) {}
01197 Element(int i, int64 j) : var(i), value(j) {}
01198 int var;
01199 int64 value;
01200 };
01201
01202 string DebugStringInternal(const string& name) const;
01203
01204 scoped_array<IntVar*> vars_;
01205 int size_;
01206 scoped_ptr<ResultCallback2<int64, int64, int64> > evaluator_;
01207 };
01208
01209 BaseEvaluatorSelector::BaseEvaluatorSelector(
01210 const IntVar* const* vars,
01211 int size,
01212 ResultCallback2<int64, int64, int64>* evaluator)
01213 : vars_(NULL), size_(size), evaluator_(evaluator) {
01214 CHECK_GE(size_, 0);
01215 if (size_ > 0) {
01216 vars_.reset(new IntVar*[size_]);
01217 memcpy(vars_.get(), vars, size_ * sizeof(*vars));
01218 }
01219 }
01220
01221
01222 string BaseEvaluatorSelector::DebugStringInternal(const string& name) const {
01223 string out = name + "(";
01224 out.append(DebugStringArray(vars_.get(), size_, ", "));
01225 out.append(")");
01226 return out;
01227 }
01228
01229
01230
01231 class DynamicEvaluatorSelector : public BaseEvaluatorSelector {
01232 public:
01233 DynamicEvaluatorSelector(const IntVar* const* vars, int size,
01234 ResultCallback2<int64, int64, int64>* evaluator,
01235 ResultCallback1<int64, int64>* tie_breaker);
01236 virtual ~DynamicEvaluatorSelector() {}
01237 virtual int64 SelectValue(const IntVar* const var, int64 id);
01238 virtual IntVar* SelectVariable(Solver* const s, int64* id);
01239 virtual string DebugString() const;
01240
01241 private:
01242 int first_;
01243 scoped_ptr<ResultCallback1<int64, int64> > tie_breaker_;
01244 std::vector<Element> cache_;
01245 };
01246
01247 DynamicEvaluatorSelector::DynamicEvaluatorSelector(
01248 const IntVar* const* vars, int size,
01249 ResultCallback2<int64, int64, int64>* evaluator,
01250 ResultCallback1<int64, int64>* tie_breaker)
01251 : BaseEvaluatorSelector(vars, size, evaluator),
01252 first_(-1), tie_breaker_(tie_breaker) {}
01253
01254 int64 DynamicEvaluatorSelector::SelectValue(const IntVar* const var, int64 id) {
01255 return cache_[first_].value;
01256 }
01257
01258 IntVar* DynamicEvaluatorSelector::SelectVariable(Solver* const s, int64* id) {
01259 int64 best_evaluation = kint64max;
01260 cache_.clear();
01261 for (int i = 0; i < size_; ++i) {
01262 const IntVar* const var = vars_[i];
01263 if (!var->Bound()) {
01264 scoped_ptr<IntVarIterator> it(var->MakeDomainIterator(false));
01265 for (it->Init(); it->Ok(); it->Next()) {
01266 const int j = it->Value();
01267 const int64 value = evaluator_->Run(i, j);
01268 if (value < best_evaluation) {
01269 best_evaluation = value;
01270 cache_.clear();
01271 cache_.push_back(Element(i, j));
01272 } else if (value == best_evaluation && tie_breaker_.get() != NULL) {
01273 cache_.push_back(Element(i, j));
01274 }
01275 }
01276 }
01277 }
01278 if (cache_.size() == 0) {
01279 *id = kint64max;
01280 return NULL;
01281 }
01282 if (tie_breaker_.get() == NULL || cache_.size() == 1) {
01283 *id = cache_[0].var;
01284 first_ = 0;
01285 return vars_[*id];
01286 } else {
01287 first_ = tie_breaker_->Run(cache_.size());
01288 *id = cache_[first_].var;
01289 return vars_[*id];
01290 }
01291 }
01292
01293 string DynamicEvaluatorSelector::DebugString() const {
01294 return DebugStringInternal("AssignVariablesOnDynamicEvaluator");
01295 }
01296
01297
01298
01299 class StaticEvaluatorSelector : public BaseEvaluatorSelector {
01300 public:
01301 StaticEvaluatorSelector(const IntVar* const* vars, int size,
01302 ResultCallback2<int64, int64, int64>* evaluator);
01303 virtual ~StaticEvaluatorSelector() {}
01304 virtual int64 SelectValue(const IntVar* const var, int64 id);
01305 virtual IntVar* SelectVariable(Solver* const s, int64* id);
01306 virtual string DebugString() const;
01307
01308 private:
01309 class Compare {
01310 public:
01311 explicit Compare(ResultCallback2<int64, int64, int64>* evaluator)
01312 : evaluator_(evaluator) {}
01313 bool operator() (const Element& lhs, const Element& rhs) const {
01314 const int64 value_lhs = Value(lhs);
01315 const int64 value_rhs = Value(rhs);
01316 return value_lhs < value_rhs
01317 || (value_lhs == value_rhs
01318 && (lhs.var < rhs.var
01319 || (lhs.var == rhs.var && lhs.value < rhs.value)));
01320 }
01321 int64 Value(const Element& element) const {
01322 return evaluator_->Run(element.var, element.value);
01323 }
01324
01325 private:
01326 ResultCallback2<int64, int64, int64>* evaluator_;
01327 };
01328
01329 Compare comp_;
01330 scoped_array<Element> elements_;
01331 int element_size_;
01332 int first_;
01333 };
01334
01335 StaticEvaluatorSelector::StaticEvaluatorSelector(
01336 const IntVar* const* vars, int size,
01337 ResultCallback2<int64, int64, int64>* evaluator)
01338 : BaseEvaluatorSelector(vars, size, evaluator),
01339 comp_(evaluator), elements_(NULL), element_size_(0), first_(-1) {}
01340
01341 int64 StaticEvaluatorSelector::SelectValue(const IntVar* const var, int64 id) {
01342 return elements_[first_].value;
01343 }
01344
01345 IntVar* StaticEvaluatorSelector::SelectVariable(Solver* const s, int64* id) {
01346 if (first_ == -1) {
01347
01348 element_size_ = 0;
01349 for (int i = 0; i < size_; ++i) {
01350 if (!vars_[i]->Bound()) {
01351 element_size_ += vars_[i]->Size();
01352 }
01353 }
01354 elements_.reset(new Element[element_size_]);
01355 int count = 0;
01356 for (int i = 0; i < size_; ++i) {
01357 const IntVar* const var = vars_[i];
01358 if (!var->Bound()) {
01359 scoped_ptr<IntVarIterator> it(var->MakeDomainIterator(false));
01360 for (it->Init(); it->Ok(); it->Next()) {
01361 const int j = it->Value();
01362 Element element(i, j);
01363 elements_[count] = element;
01364 ++count;
01365 }
01366 }
01367 }
01368
01369 std::sort(elements_.get(), elements_.get() + element_size_, comp_);
01370 s->SaveAndSetValue(&first_, 0);
01371 }
01372 for (int i = first_; i < element_size_; ++i) {
01373 const Element& element = elements_[i];
01374 IntVar* const var = vars_[element.var];
01375 if (!var->Bound() && var->Contains(element.value)) {
01376 s->SaveAndSetValue(&first_, i);
01377 *id = element.var;
01378 return var;
01379 }
01380 }
01381 s->SaveAndSetValue(&first_, element_size_);
01382 *id = size_;
01383 return NULL;
01384 }
01385
01386 string StaticEvaluatorSelector::DebugString() const {
01387 return DebugStringInternal("AssignVariablesOnStaticEvaluator");
01388 }
01389
01390
01391
01392 class AssignOneVariableValue : public Decision {
01393 public:
01394 AssignOneVariableValue(IntVar* const v, int64 val);
01395 virtual ~AssignOneVariableValue() {}
01396 virtual void Apply(Solver* const s);
01397 virtual void Refute(Solver* const s);
01398 virtual string DebugString() const;
01399 virtual void Accept(DecisionVisitor* const visitor) const {
01400 visitor->VisitSetVariableValue(var_, value_);
01401 }
01402
01403 private:
01404 IntVar* const var_;
01405 int64 value_;
01406 };
01407
01408 AssignOneVariableValue::AssignOneVariableValue(IntVar* const v, int64 val)
01409 : var_(v), value_(val) {
01410 }
01411
01412 string AssignOneVariableValue::DebugString() const {
01413 return StringPrintf("[%s == %" GG_LL_FORMAT "d]",
01414 var_->DebugString().c_str(), value_);
01415 }
01416
01417 void AssignOneVariableValue::Apply(Solver* const s) {
01418 var_->SetValue(value_);
01419 }
01420
01421 void AssignOneVariableValue::Refute(Solver* const s) {
01422 var_->RemoveValue(value_);
01423 }
01424 }
01425
01426 Decision* Solver::MakeAssignVariableValue(IntVar* const v, int64 val) {
01427 return RevAlloc(new AssignOneVariableValue(v, val));
01428 }
01429
01430
01431
01432 namespace {
01433 class AssignOneVariableValueOrFail : public Decision {
01434 public:
01435 AssignOneVariableValueOrFail(IntVar* const v, int64 value);
01436 virtual ~AssignOneVariableValueOrFail() {}
01437 virtual void Apply(Solver* const s);
01438 virtual void Refute(Solver* const s);
01439 virtual string DebugString() const;
01440 virtual void Accept(DecisionVisitor* const visitor) const {
01441 visitor->VisitSetVariableValue(var_, value_);
01442 }
01443
01444 private:
01445 IntVar* const var_;
01446 const int64 value_;
01447 };
01448
01449 AssignOneVariableValueOrFail::AssignOneVariableValueOrFail(IntVar* const v,
01450 int64 value)
01451 : var_(v), value_(value) {
01452 }
01453
01454 string AssignOneVariableValueOrFail::DebugString() const {
01455 return StringPrintf("[%s == %" GG_LL_FORMAT "d]",
01456 var_->DebugString().c_str(), value_);
01457 }
01458
01459 void AssignOneVariableValueOrFail::Apply(Solver* const s) {
01460 var_->SetValue(value_);
01461 }
01462
01463 void AssignOneVariableValueOrFail::Refute(Solver* const s) {
01464 s->Fail();
01465 }
01466 }
01467
01468 Decision* Solver::MakeAssignVariableValueOrFail(IntVar* const v, int64 value) {
01469 return RevAlloc(new AssignOneVariableValueOrFail(v, value));
01470 }
01471
01472
01473
01474 namespace {
01475 class SplitOneVariable : public Decision {
01476 public:
01477 SplitOneVariable(IntVar* const v, int64 val, bool start_with_lower_half);
01478 virtual ~SplitOneVariable() {}
01479 virtual void Apply(Solver* const s);
01480 virtual void Refute(Solver* const s);
01481 virtual string DebugString() const;
01482 virtual void Accept(DecisionVisitor* const visitor) const {
01483 visitor->VisitSplitVariableDomain(var_, value_, start_with_lower_half_);
01484 }
01485
01486 private:
01487 IntVar* const var_;
01488 const int64 value_;
01489 const bool start_with_lower_half_;
01490 };
01491
01492 SplitOneVariable::SplitOneVariable(IntVar* const v,
01493 int64 val,
01494 bool start_with_lower_half)
01495 : var_(v), value_(val), start_with_lower_half_(start_with_lower_half) {
01496 }
01497
01498 string SplitOneVariable::DebugString() const {
01499 if (start_with_lower_half_) {
01500 return StringPrintf("[%s <= %" GG_LL_FORMAT "d]",
01501 var_->DebugString().c_str(), value_);
01502 } else {
01503 return StringPrintf("[%s >= %" GG_LL_FORMAT "d]",
01504 var_->DebugString().c_str(), value_);
01505 }
01506 }
01507
01508 void SplitOneVariable::Apply(Solver* const s) {
01509 if (start_with_lower_half_) {
01510 var_->SetMax(value_);
01511 } else {
01512 var_->SetMin(value_);
01513 }
01514 }
01515
01516 void SplitOneVariable::Refute(Solver* const s) {
01517 if (start_with_lower_half_) {
01518 var_->SetMin(value_ + 1);
01519 } else {
01520 var_->SetMax(value_ - 1);
01521 }
01522 }
01523 }
01524
01525 Decision* Solver::MakeSplitVariableDomain(IntVar* const v,
01526 int64 val,
01527 bool start_with_lower_half) {
01528 return RevAlloc(new SplitOneVariable(v, val, start_with_lower_half));
01529 }
01530
01531 Decision* Solver::MakeVariableLessOrEqualValue(IntVar* const var, int64 value) {
01532 return MakeSplitVariableDomain(var, value, true);
01533 }
01534
01535 Decision* Solver::MakeVariableGreaterOrEqualValue(IntVar* const var,
01536 int64 value) {
01537 return MakeSplitVariableDomain(var, value, false);
01538 }
01539
01540
01541
01542
01543 namespace {
01544 class AssignVariablesValues : public Decision {
01545 public:
01546 AssignVariablesValues(const IntVar* const* vars, int size,
01547 const int64* const values);
01548 virtual ~AssignVariablesValues() {}
01549 virtual void Apply(Solver* const s);
01550 virtual void Refute(Solver* const s);
01551 virtual string DebugString() const;
01552 virtual void Accept(DecisionVisitor* const visitor) const {
01553 for (int i = 0; i < size_; ++i) {
01554 visitor->VisitSetVariableValue(vars_[i], values_[i]);
01555 }
01556 }
01557
01558 virtual void Accept(ModelVisitor* const visitor) const {
01559 visitor->BeginVisitExtension(ModelVisitor::kVariableGroupExtension);
01560 visitor->VisitIntegerVariableArrayArgument(ModelVisitor::kVarsArgument,
01561 vars_.get(),
01562 size_);
01563 visitor->EndVisitExtension(ModelVisitor::kVariableGroupExtension);
01564 }
01565
01566 private:
01567 scoped_array<IntVar*> vars_;
01568 scoped_array<int64> values_;
01569 int size_;
01570 };
01571
01572 AssignVariablesValues::AssignVariablesValues(const IntVar* const* vars,
01573 int size,
01574 const int64* const values)
01575 : vars_(NULL), values_(NULL), size_(size) {
01576 CHECK_GE(size_, 0);
01577 if (size_ > 0) {
01578 vars_.reset(new IntVar*[size_]);
01579 memcpy(vars_.get(), vars, size_ * sizeof(*vars));
01580 values_.reset(new int64[size_]);
01581 memcpy(values_.get(), values, size_ * sizeof(*values));
01582 }
01583 }
01584
01585 string AssignVariablesValues::DebugString() const {
01586 string out;
01587 for (int i = 0; i < size_; ++i) {
01588 StringAppendF(&out, "[%s == %" GG_LL_FORMAT "d]",
01589 vars_[i]->DebugString().c_str(), values_[i]);
01590 }
01591 return out;
01592 }
01593
01594 void AssignVariablesValues::Apply(Solver* const s) {
01595 for (int i = 0; i < size_; ++i) {
01596 vars_[i]->SetValue(values_[i]);
01597 }
01598 }
01599
01600 void AssignVariablesValues::Refute(Solver* const s) {
01601 std::vector<IntVar*> terms;
01602 for (int i = 0; i < size_; ++i) {
01603 IntVar* term = s->MakeBoolVar();
01604 s->MakeIsDifferentCstCt(vars_[i], values_[i], term);
01605 terms.push_back(term);
01606 }
01607 s->AddConstraint(s->MakeSumGreaterOrEqual(terms, 1));
01608 }
01609 }
01610
01611 Decision* Solver::MakeAssignVariablesValues(const IntVar* const* vars, int size,
01612 const int64* const values) {
01613 return RevAlloc(new AssignVariablesValues(vars, size, values));
01614 }
01615
01616 Decision* Solver::MakeAssignVariablesValues(const std::vector<IntVar*>& vars,
01617 const std::vector<int64>& values) {
01618 CHECK_EQ(vars.size(), values.size());
01619 return RevAlloc(new AssignVariablesValues(vars.data(), vars.size(),
01620 values.data()));
01621 }
01622
01623
01624
01625 namespace {
01626 class BaseAssignVariables : public DecisionBuilder {
01627 public:
01628 explicit BaseAssignVariables(BaseVariableAssignmentSelector* const selector)
01629 : selector_(selector) {}
01630 virtual ~BaseAssignVariables();
01631 virtual Decision* Next(Solver* const s);
01632 virtual string DebugString() const;
01633 static BaseAssignVariables* MakePhase(Solver* const s,
01634 const IntVar* const* vars,
01635 int size,
01636 VariableSelector* const var_selector,
01637 ValueSelector* const value_selector);
01638 static VariableSelector* MakeVariableSelector(Solver* const s,
01639 const IntVar* const* vars,
01640 int size,
01641 Solver::IntVarStrategy str) {
01642 VariableSelector* var_selector = NULL;
01643 switch (str) {
01644 case Solver::INT_VAR_DEFAULT:
01645 case Solver::INT_VAR_SIMPLE:
01646 case Solver::CHOOSE_FIRST_UNBOUND:
01647 var_selector = s->RevAlloc(new FirstUnboundSelector(vars, size));
01648 break;
01649 case Solver::CHOOSE_RANDOM:
01650 var_selector = s->RevAlloc(new RandomSelector(vars, size));
01651 break;
01652 case Solver::CHOOSE_MIN_SIZE_LOWEST_MIN:
01653 var_selector = s->RevAlloc(new MinSizeLowestMinSelector(vars, size));
01654 break;
01655 case Solver::CHOOSE_MIN_SIZE_HIGHEST_MIN:
01656 var_selector = s->RevAlloc(new MinSizeHighestMinSelector(vars, size));
01657 break;
01658 case Solver::CHOOSE_MIN_SIZE_LOWEST_MAX:
01659 var_selector = s->RevAlloc(new MinSizeLowestMaxSelector(vars, size));
01660 break;
01661 case Solver::CHOOSE_MIN_SIZE_HIGHEST_MAX:
01662 var_selector = s->RevAlloc(new MinSizeHighestMaxSelector(vars, size));
01663 break;
01664 case Solver::CHOOSE_PATH:
01665 var_selector = s->RevAlloc(new PathSelector(vars, size));
01666 break;
01667 default:
01668 LOG(FATAL) << "Unknown int var strategy " << str;
01669 break;
01670 }
01671 return var_selector;
01672 }
01673
01674 static ValueSelector* MakeValueSelector(Solver* const s,
01675 Solver::IntValueStrategy val_str) {
01676 ValueSelector* value_selector = NULL;
01677 switch (val_str) {
01678 case Solver::INT_VALUE_DEFAULT:
01679 case Solver::INT_VALUE_SIMPLE:
01680 case Solver::ASSIGN_MIN_VALUE:
01681 value_selector = s->RevAlloc(new MinValueSelector);
01682 break;
01683 case Solver::ASSIGN_MAX_VALUE:
01684 value_selector = s->RevAlloc(new MaxValueSelector);
01685 break;
01686 case Solver::ASSIGN_RANDOM_VALUE:
01687 value_selector = s->RevAlloc(new RandomValueSelector);
01688 break;
01689 case Solver::ASSIGN_CENTER_VALUE:
01690 value_selector = s->RevAlloc(new CenterValueSelector);
01691 break;
01692 default:
01693 LOG(FATAL) << "Unknown int value strategy " << val_str;
01694 break;
01695 }
01696 return value_selector;
01697 }
01698
01699 virtual void Accept(ModelVisitor* const visitor) const {
01700 selector_->Accept(visitor);
01701 }
01702
01703 protected:
01704 BaseVariableAssignmentSelector* const selector_;
01705 };
01706
01707 BaseAssignVariables::~BaseAssignVariables() {}
01708
01709 Decision* BaseAssignVariables::Next(Solver* const s) {
01710 int64 id = 0;
01711 IntVar* const var = selector_->SelectVariable(s, &id);
01712 if (NULL != var) {
01713 const int64 value = selector_->SelectValue(var, id);
01714 return s->RevAlloc(new AssignOneVariableValue(var, value));
01715 }
01716 return NULL;
01717 }
01718
01719 string BaseAssignVariables::DebugString() const {
01720 return selector_->DebugString();
01721 }
01722
01723 BaseAssignVariables*
01724 BaseAssignVariables::MakePhase(Solver* const s,
01725 const IntVar* const* vars,
01726 int size,
01727 VariableSelector* const var_selector,
01728 ValueSelector* const value_selector) {
01729 BaseVariableAssignmentSelector* selector =
01730 s->RevAlloc(new VariableAssignmentSelector(var_selector, value_selector));
01731 return s->RevAlloc(new BaseAssignVariables(selector));
01732 }
01733 }
01734
01735 DecisionBuilder* Solver::MakePhase(IntVar* const v0,
01736 Solver::IntVarStrategy var_str,
01737 Solver::IntValueStrategy val_str) {
01738 scoped_array<IntVar*> vars(new IntVar*[1]);
01739 vars[0] = v0;
01740 return MakePhase(vars.get(), 1, var_str, val_str);
01741 }
01742
01743 DecisionBuilder* Solver::MakePhase(IntVar* const v0,
01744 IntVar* const v1,
01745 Solver::IntVarStrategy var_str,
01746 Solver::IntValueStrategy val_str) {
01747 scoped_array<IntVar*> vars(new IntVar*[2]);
01748 vars[0] = v0;
01749 vars[1] = v1;
01750 return MakePhase(vars.get(), 2, var_str, val_str);
01751 }
01752
01753 DecisionBuilder* Solver::MakePhase(IntVar* const v0,
01754 IntVar* const v1,
01755 IntVar* const v2,
01756 Solver::IntVarStrategy var_str,
01757 Solver::IntValueStrategy val_str) {
01758 scoped_array<IntVar*> vars(new IntVar*[3]);
01759 vars[0] = v0;
01760 vars[1] = v1;
01761 vars[2] = v2;
01762 return MakePhase(vars.get(), 3, var_str, val_str);
01763 }
01764
01765 DecisionBuilder* Solver::MakePhase(IntVar* const v0,
01766 IntVar* const v1,
01767 IntVar* const v2,
01768 IntVar* const v3,
01769 Solver::IntVarStrategy var_str,
01770 Solver::IntValueStrategy val_str) {
01771 scoped_array<IntVar*> vars(new IntVar*[4]);
01772 vars[0] = v0;
01773 vars[1] = v1;
01774 vars[2] = v2;
01775 vars[3] = v3;
01776 return MakePhase(vars.get(), 4, var_str, val_str);
01777 }
01778
01779 DecisionBuilder* Solver::MakePhase(const std::vector<IntVar*>& vars,
01780 Solver::IntVarStrategy var_str,
01781 Solver::IntValueStrategy val_str) {
01782 return MakePhase(vars.data(), vars.size(), var_str, val_str);
01783 }
01784
01785 DecisionBuilder* Solver::MakePhase(const IntVar* const* vars,
01786 int size,
01787 Solver::IntVarStrategy var_str,
01788 Solver::IntValueStrategy val_str) {
01789 VariableSelector* const var_selector =
01790 BaseAssignVariables::MakeVariableSelector(this,
01791 vars,
01792 size,
01793 var_str);
01794 ValueSelector* const value_selector =
01795 BaseAssignVariables::MakeValueSelector(this, val_str);
01796 return BaseAssignVariables::MakePhase(this,
01797 vars,
01798 size,
01799 var_selector,
01800 value_selector);
01801 }
01802
01803 DecisionBuilder* Solver::MakePhase(const std::vector<IntVar*>& vars,
01804 ResultCallback1<int64, int64>* var_evaluator,
01805 Solver::IntValueStrategy val_str) {
01806 return MakePhase(vars.data(), vars.size(), var_evaluator, val_str);
01807 }
01808
01809 DecisionBuilder* Solver::MakePhase(const IntVar* const* vars,
01810 int size,
01811 ResultCallback1<int64, int64>* var_evaluator,
01812 Solver::IntValueStrategy val_str) {
01813 var_evaluator->CheckIsRepeatable();
01814 VariableSelector* const var_selector =
01815 RevAlloc(new CheapestVarSelector(vars, size, var_evaluator));
01816 ValueSelector* const value_selector =
01817 BaseAssignVariables::MakeValueSelector(this, val_str);
01818 return BaseAssignVariables::MakePhase(this,
01819 vars,
01820 size,
01821 var_selector,
01822 value_selector);
01823 }
01824
01825 DecisionBuilder* Solver::MakePhase(
01826 const std::vector<IntVar*>& vars,
01827 Solver::IntVarStrategy var_str,
01828 ResultCallback2<int64, int64, int64>* value_evaluator) {
01829 return MakePhase(vars.data(), vars.size(), var_str, value_evaluator);
01830 }
01831
01832 DecisionBuilder* Solver::MakePhase(
01833 const IntVar* const* vars,
01834 int size,
01835 Solver::IntVarStrategy var_str,
01836 ResultCallback2<int64, int64, int64>* value_evaluator) {
01837 VariableSelector* const var_selector =
01838 BaseAssignVariables::MakeVariableSelector(this,
01839 vars,
01840 size,
01841 var_str);
01842 value_evaluator->CheckIsRepeatable();
01843 ValueSelector* value_selector =
01844 RevAlloc(new CheapestValueSelector(value_evaluator, NULL));
01845 return BaseAssignVariables::MakePhase(this,
01846 vars,
01847 size,
01848 var_selector,
01849 value_selector);
01850 }
01851
01852 DecisionBuilder* Solver::MakePhase(
01853 const std::vector<IntVar*>& vars,
01854 ResultCallback1<int64, int64>* var_evaluator,
01855 ResultCallback2<int64, int64, int64>* value_evaluator) {
01856 return MakePhase(vars.data(), vars.size(), var_evaluator, value_evaluator);
01857 }
01858
01859 DecisionBuilder* Solver::MakePhase(
01860 const IntVar* const* vars,
01861 int size,
01862 ResultCallback1<int64, int64>* var_evaluator,
01863 ResultCallback2<int64, int64, int64>* value_evaluator) {
01864 var_evaluator->CheckIsRepeatable();
01865 VariableSelector* const var_selector =
01866 RevAlloc(new CheapestVarSelector(vars, size, var_evaluator));
01867 value_evaluator->CheckIsRepeatable();
01868 ValueSelector* value_selector =
01869 RevAlloc(new CheapestValueSelector(value_evaluator, NULL));
01870 return BaseAssignVariables::MakePhase(this,
01871 vars,
01872 size,
01873 var_selector,
01874 value_selector);
01875 }
01876
01877 DecisionBuilder* Solver::MakePhase(
01878 const std::vector<IntVar*>& vars,
01879 Solver::IntVarStrategy var_str,
01880 ResultCallback2<int64, int64, int64>* value_evaluator,
01881 ResultCallback1<int64, int64>* tie_breaker) {
01882 return MakePhase(vars.data(), vars.size(), var_str, value_evaluator,
01883 tie_breaker);
01884 }
01885
01886 DecisionBuilder* Solver::MakePhase(
01887 const IntVar* const* vars,
01888 int size,
01889 Solver::IntVarStrategy var_str,
01890 ResultCallback2<int64, int64, int64>* value_evaluator,
01891 ResultCallback1<int64, int64>* tie_breaker) {
01892 VariableSelector* const var_selector =
01893 BaseAssignVariables::MakeVariableSelector(this,
01894 vars,
01895 size,
01896 var_str);
01897 value_evaluator->CheckIsRepeatable();
01898 ValueSelector* value_selector =
01899 RevAlloc(new CheapestValueSelector(value_evaluator, tie_breaker));
01900 return BaseAssignVariables::MakePhase(this,
01901 vars,
01902 size,
01903 var_selector,
01904 value_selector);
01905 }
01906
01907 DecisionBuilder* Solver::MakePhase(
01908 const std::vector<IntVar*>& vars,
01909 ResultCallback1<int64, int64>* var_evaluator,
01910 ResultCallback2<int64, int64, int64>* value_evaluator,
01911 ResultCallback1<int64, int64>* tie_breaker) {
01912 return MakePhase(vars.data(), vars.size(), var_evaluator,
01913 value_evaluator, tie_breaker);
01914 }
01915
01916 DecisionBuilder* Solver::MakePhase(
01917 const IntVar* const* vars,
01918 int size,
01919 ResultCallback1<int64, int64>* var_evaluator,
01920 ResultCallback2<int64, int64, int64>* value_evaluator,
01921 ResultCallback1<int64, int64>* tie_breaker) {
01922 var_evaluator->CheckIsRepeatable();
01923 VariableSelector* const var_selector =
01924 RevAlloc(new CheapestVarSelector(vars, size, var_evaluator));
01925 value_evaluator->CheckIsRepeatable();
01926 ValueSelector* value_selector =
01927 RevAlloc(new CheapestValueSelector(value_evaluator, tie_breaker));
01928 return BaseAssignVariables::MakePhase(this,
01929 vars,
01930 size,
01931 var_selector,
01932 value_selector);
01933 }
01934
01935 DecisionBuilder* Solver::MakePhase(const std::vector<IntVar*>& vars,
01936 ResultCallback2<int64, int64, int64>* eval,
01937 Solver::EvaluatorStrategy str) {
01938 return MakePhase(vars.data(), vars.size(), eval, str);
01939 }
01940
01941 DecisionBuilder* Solver::MakePhase(const IntVar* const* vars,
01942 int size,
01943 ResultCallback2<int64, int64, int64>* eval,
01944 Solver::EvaluatorStrategy str) {
01945 return MakePhase(vars, size, eval, NULL, str);
01946 }
01947
01948 DecisionBuilder* Solver::MakePhase(const std::vector<IntVar*>& vars,
01949 ResultCallback2<int64, int64, int64>* eval,
01950 ResultCallback1<int64, int64>* tie_breaker,
01951 Solver::EvaluatorStrategy str) {
01952 return MakePhase(vars.data(), vars.size(), eval, tie_breaker, str);
01953 }
01954
01955 DecisionBuilder* Solver::MakePhase(const IntVar* const* vars,
01956 int size,
01957 ResultCallback2<int64, int64, int64>* eval,
01958 ResultCallback1<int64, int64>* tie_breaker,
01959 Solver::EvaluatorStrategy str) {
01960 eval->CheckIsRepeatable();
01961 if (tie_breaker) {
01962 tie_breaker->CheckIsRepeatable();
01963 }
01964 BaseVariableAssignmentSelector* selector = NULL;
01965 switch (str) {
01966 case Solver::CHOOSE_STATIC_GLOBAL_BEST: {
01967
01968 selector = RevAlloc(new StaticEvaluatorSelector(vars, size, eval));
01969 break;
01970 }
01971 case Solver::CHOOSE_DYNAMIC_GLOBAL_BEST: {
01972 selector = RevAlloc(new DynamicEvaluatorSelector(vars, size, eval,
01973 tie_breaker));
01974 break;
01975 }
01976 }
01977 return RevAlloc(new BaseAssignVariables(selector));
01978 }
01979
01980
01981
01982 namespace {
01983 class AssignVariablesFromAssignment : public DecisionBuilder {
01984 public:
01985 AssignVariablesFromAssignment(const Assignment* const assignment,
01986 DecisionBuilder* const db,
01987 const IntVar* const* vars,
01988 int size) :
01989 assignment_(assignment),
01990 db_(db),
01991 size_(size),
01992 iter_(0) {
01993 CHECK_GE(size_, 0);
01994 if (size_ > 0) {
01995 vars_.reset(new IntVar*[size_]);
01996 memcpy(vars_.get(), vars, size_ * sizeof(*vars));
01997 }
01998 }
01999
02000 ~AssignVariablesFromAssignment() {}
02001
02002 Decision* Next(Solver* const s) {
02003 if (iter_ < size_) {
02004 IntVar* const var = vars_[iter_++];
02005 return s->RevAlloc(new AssignOneVariableValue(var,
02006 assignment_->Value(var)));
02007 } else {
02008 return db_->Next(s);
02009 }
02010 }
02011
02012 virtual void Accept(ModelVisitor* const visitor) const {
02013 visitor->BeginVisitExtension(ModelVisitor::kVariableGroupExtension);
02014 visitor->VisitIntegerVariableArrayArgument(ModelVisitor::kVarsArgument,
02015 vars_.get(),
02016 size_);
02017 visitor->EndVisitExtension(ModelVisitor::kVariableGroupExtension);
02018 }
02019
02020 private:
02021 const Assignment* const assignment_;
02022 DecisionBuilder* const db_;
02023 scoped_array<IntVar*> vars_;
02024 int size_;
02025 int iter_;
02026 };
02027 }
02028
02029 DecisionBuilder* Solver::MakeDecisionBuilderFromAssignment(
02030 Assignment* const assignment,
02031 DecisionBuilder* const db,
02032 const IntVar* const* vars,
02033 int size) {
02034 return RevAlloc(new AssignVariablesFromAssignment(assignment,
02035 db,
02036 vars,
02037 size));
02038 }
02039
02040
02041
02042
02043
02044 SolutionCollector::SolutionCollector(Solver* const s, const Assignment* const a)
02045 : SearchMonitor(s), prototype_(a == NULL ? NULL : new Assignment(a)) {}
02046
02047 SolutionCollector::SolutionCollector(Solver* const s)
02048 : SearchMonitor(s), prototype_(new Assignment(s)) {}
02049
02050 SolutionCollector::~SolutionCollector() {
02051 STLDeleteElements(&solutions_);
02052 STLDeleteElements(&recycle_solutions_);
02053 }
02054
02055 void SolutionCollector::Add(IntVar* const var) {
02056 if (prototype_.get() != NULL) {
02057 prototype_->Add(var);
02058 }
02059 }
02060
02061 void SolutionCollector::Add(const std::vector<IntVar*>& vars) {
02062 if (prototype_.get() != NULL) {
02063 prototype_->Add(vars);
02064 }
02065 }
02066
02067 void SolutionCollector::Add(IntervalVar* const var) {
02068 if (prototype_.get() != NULL) {
02069 prototype_->Add(var);
02070 }
02071 }
02072
02073 void SolutionCollector::Add(const std::vector<IntervalVar*>& vars) {
02074 if (prototype_.get() != NULL) {
02075 prototype_->Add(vars);
02076 }
02077 }
02078
02079 void SolutionCollector::AddObjective(IntVar* const objective) {
02080 if (prototype_.get() != NULL && objective != NULL) {
02081 prototype_->AddObjective(objective);
02082 }
02083 }
02084
02085 void SolutionCollector::EnterSearch() {
02086 STLDeleteElements(&solutions_);
02087 STLDeleteElements(&recycle_solutions_);
02088 solutions_.clear();
02089 recycle_solutions_.clear();
02090 times_.clear();
02091 branches_.clear();
02092 failures_.clear();
02093 objective_values_.clear();
02094 }
02095
02096 void SolutionCollector::PushSolution() {
02097 Assignment* new_sol = NULL;
02098 if (prototype_.get() != NULL) {
02099 if (!recycle_solutions_.empty()) {
02100 new_sol = recycle_solutions_.back();
02101 DCHECK(new_sol != NULL);
02102 recycle_solutions_.pop_back();
02103 } else {
02104 new_sol = new Assignment(prototype_.get());
02105 }
02106 new_sol->Store();
02107 }
02108 Solver* const s = solver();
02109 solutions_.push_back(new_sol);
02110 times_.push_back(s->wall_time());
02111 branches_.push_back(s->branches());
02112 failures_.push_back(s->failures());
02113 if (new_sol != NULL) {
02114 objective_values_.push_back(new_sol->ObjectiveValue());
02115 } else {
02116 objective_values_.push_back(0);
02117 }
02118 }
02119
02120 void SolutionCollector::PopSolution() {
02121 if (!solutions_.empty()) {
02122 Assignment* popped = solutions_.back();
02123 solutions_.pop_back();
02124 if (popped != NULL) {
02125 recycle_solutions_.push_back(popped);
02126 }
02127 times_.pop_back();
02128 branches_.pop_back();
02129 failures_.pop_back();
02130 objective_values_.pop_back();
02131 }
02132 }
02133
02134 void SolutionCollector::check_index(int n) const {
02135 CHECK_GE(n, 0) << "wrong index in solution getter";
02136 CHECK_LT(n, solutions_.size()) << "wrong index in solution getter";
02137 }
02138
02139 Assignment* SolutionCollector::solution(int n) const {
02140 check_index(n);
02141 return solutions_[n];
02142 }
02143
02144 int SolutionCollector::solution_count() const {
02145 return solutions_.size();
02146 }
02147
02148 int64 SolutionCollector::wall_time(int n) const {
02149 check_index(n);
02150 return times_[n];
02151 }
02152
02153 int64 SolutionCollector::branches(int n) const {
02154 check_index(n);
02155 return branches_[n];
02156 }
02157
02158 int64 SolutionCollector::failures(int n) const {
02159 check_index(n);
02160 return failures_[n];
02161 }
02162
02163 int64 SolutionCollector::objective_value(int n) const {
02164 check_index(n);
02165 return objective_values_[n];
02166 }
02167
02168 int64 SolutionCollector::Value(int n, IntVar* const var) const {
02169 check_index(n);
02170 return solutions_[n]->Value(var);
02171 }
02172
02173 int64 SolutionCollector::StartValue(int n, IntervalVar* const var) const {
02174 check_index(n);
02175 return solutions_[n]->StartValue(var);
02176 }
02177
02178 int64 SolutionCollector::DurationValue(int n, IntervalVar* const var) const {
02179 check_index(n);
02180 return solutions_[n]->DurationValue(var);
02181 }
02182
02183 int64 SolutionCollector::EndValue(int n, IntervalVar* const var) const {
02184 check_index(n);
02185 return solutions_[n]->EndValue(var);
02186 }
02187
02188 int64 SolutionCollector::PerformedValue(int n, IntervalVar* const var) const {
02189 check_index(n);
02190 return solutions_[n]->PerformedValue(var);
02191 }
02192
02193 namespace {
02194
02195
02196
02197 class FirstSolutionCollector : public SolutionCollector {
02198 public:
02199 FirstSolutionCollector(Solver* const s, const Assignment* const a);
02200 explicit FirstSolutionCollector(Solver* const s);
02201 virtual ~FirstSolutionCollector();
02202 virtual void EnterSearch();
02203 virtual bool AtSolution();
02204 virtual string DebugString() const;
02205
02206 private:
02207 bool done_;
02208 };
02209
02210 FirstSolutionCollector::FirstSolutionCollector(Solver* const s,
02211 const Assignment* const a)
02212 : SolutionCollector(s, a), done_(false) {}
02213
02214 FirstSolutionCollector::FirstSolutionCollector(Solver* const s)
02215 : SolutionCollector(s), done_(false) {}
02216
02217 FirstSolutionCollector::~FirstSolutionCollector() {}
02218
02219 void FirstSolutionCollector::EnterSearch() {
02220 SolutionCollector::EnterSearch();
02221 done_ = false;
02222 }
02223
02224 bool FirstSolutionCollector::AtSolution() {
02225 if (!done_) {
02226 PushSolution();
02227 done_ = true;
02228 }
02229 return false;
02230 }
02231
02232 string FirstSolutionCollector::DebugString() const {
02233 if (prototype_.get() == NULL) {
02234 return "FirstSolutionCollector()";
02235 } else {
02236 return "FirstSolutionCollector(" + prototype_->DebugString() + ")";
02237 }
02238 }
02239 }
02240
02241 SolutionCollector* Solver::MakeFirstSolutionCollector(
02242 const Assignment* const a) {
02243 return RevAlloc(new FirstSolutionCollector(this, a));
02244 }
02245
02246 SolutionCollector* Solver::MakeFirstSolutionCollector() {
02247 return RevAlloc(new FirstSolutionCollector(this));
02248 }
02249
02250
02251
02252
02253 namespace {
02254 class LastSolutionCollector : public SolutionCollector {
02255 public:
02256 LastSolutionCollector(Solver* const s, const Assignment* const a);
02257 explicit LastSolutionCollector(Solver* const s);
02258 virtual ~LastSolutionCollector();
02259 virtual bool AtSolution();
02260 virtual string DebugString() const;
02261 };
02262
02263 LastSolutionCollector::LastSolutionCollector(Solver* const s,
02264 const Assignment* const a)
02265 : SolutionCollector(s, a) {}
02266
02267 LastSolutionCollector::LastSolutionCollector(Solver* const s)
02268 : SolutionCollector(s) {}
02269
02270
02271 LastSolutionCollector::~LastSolutionCollector() {}
02272
02273 bool LastSolutionCollector::AtSolution() {
02274 PopSolution();
02275 PushSolution();
02276 return true;
02277 }
02278
02279 string LastSolutionCollector::DebugString() const {
02280 if (prototype_.get() == NULL) {
02281 return "LastSolutionCollector()";
02282 } else {
02283 return "LastSolutionCollector(" + prototype_->DebugString() + ")";
02284 }
02285 }
02286 }
02287
02288 SolutionCollector* Solver::MakeLastSolutionCollector(
02289 const Assignment* const a) {
02290 return RevAlloc(new LastSolutionCollector(this, a));
02291 }
02292
02293 SolutionCollector* Solver::MakeLastSolutionCollector() {
02294 return RevAlloc(new LastSolutionCollector(this));
02295 }
02296
02297
02298
02299 namespace {
02300 class BestValueSolutionCollector : public SolutionCollector {
02301 public:
02302 BestValueSolutionCollector(Solver* const s,
02303 const Assignment* const a,
02304 bool maximize);
02305 BestValueSolutionCollector(Solver* const s, bool maximize);
02306 virtual ~BestValueSolutionCollector() {}
02307 virtual void EnterSearch();
02308 virtual bool AtSolution();
02309 virtual string DebugString() const;
02310 public:
02311 const bool maximize_;
02312 int64 best_;
02313 };
02314
02315 BestValueSolutionCollector::BestValueSolutionCollector(
02316 Solver* const s,
02317 const Assignment* const a,
02318 bool maximize)
02319 : SolutionCollector(s, a),
02320 maximize_(maximize),
02321 best_(maximize ? kint64min : kint64max) {}
02322
02323 BestValueSolutionCollector::BestValueSolutionCollector(Solver* const s,
02324 bool maximize)
02325 : SolutionCollector(s),
02326 maximize_(maximize),
02327 best_(maximize ? kint64min : kint64max) {}
02328
02329 void BestValueSolutionCollector::EnterSearch() {
02330 SolutionCollector::EnterSearch();
02331 best_ = maximize_ ? kint64min : kint64max;
02332 }
02333
02334 bool BestValueSolutionCollector::AtSolution() {
02335 if (prototype_.get() != NULL) {
02336 const IntVar* objective = prototype_->Objective();
02337 if (objective != NULL) {
02338 if (maximize_ && objective->Max() > best_) {
02339 PopSolution();
02340 PushSolution();
02341 best_ = objective->Max();
02342 } else if (!maximize_ && objective->Min() < best_) {
02343 PopSolution();
02344 PushSolution();
02345 best_ = objective->Min();
02346 }
02347 }
02348 }
02349 return true;
02350 }
02351
02352 string BestValueSolutionCollector::DebugString() const {
02353 if (prototype_.get() == NULL) {
02354 return "BestValueSolutionCollector()";
02355 } else {
02356 return "BestValueSolutionCollector(" + prototype_->DebugString() + ")";
02357 }
02358 }
02359 }
02360
02361 SolutionCollector* Solver::MakeBestValueSolutionCollector(
02362 const Assignment* const a, bool maximize) {
02363 return RevAlloc(new BestValueSolutionCollector(this, a, maximize));
02364 }
02365
02366 SolutionCollector* Solver::MakeBestValueSolutionCollector(bool maximize) {
02367 return RevAlloc(new BestValueSolutionCollector(this, maximize));
02368 }
02369
02370
02371
02372
02373 namespace {
02374 class AllSolutionCollector : public SolutionCollector {
02375 public:
02376 AllSolutionCollector(Solver* const s, const Assignment* const a);
02377 explicit AllSolutionCollector(Solver* const s);
02378 virtual ~AllSolutionCollector();
02379 virtual bool AtSolution();
02380 virtual string DebugString() const;
02381 };
02382
02383 AllSolutionCollector::AllSolutionCollector(Solver* const s,
02384 const Assignment* const a)
02385 : SolutionCollector(s, a) {}
02386
02387 AllSolutionCollector::AllSolutionCollector(Solver* const s)
02388 : SolutionCollector(s) {}
02389
02390 AllSolutionCollector::~AllSolutionCollector() {}
02391
02392 bool AllSolutionCollector::AtSolution() {
02393 PushSolution();
02394 return true;
02395 }
02396
02397 string AllSolutionCollector::DebugString() const {
02398 if (prototype_.get() == NULL) {
02399 return "AllSolutionCollector()";
02400 } else {
02401 return "AllSolutionCollector(" + prototype_->DebugString() + ")";
02402 }
02403 }
02404 }
02405
02406 SolutionCollector* Solver::MakeAllSolutionCollector(const Assignment* const a) {
02407 return RevAlloc(new AllSolutionCollector(this, a));
02408 }
02409
02410 SolutionCollector* Solver::MakeAllSolutionCollector() {
02411 return RevAlloc(new AllSolutionCollector(this));
02412 }
02413
02414
02415
02416 OptimizeVar::OptimizeVar(Solver* const s,
02417 bool maximize,
02418 IntVar* const a,
02419 int64 step)
02420 : SearchMonitor(s), var_(a), step_(step), best_(kint64max),
02421 maximize_(maximize), found_initial_solution_(false) {
02422 CHECK_GT(step, 0);
02423 }
02424
02425 OptimizeVar::~OptimizeVar() {}
02426
02427 void OptimizeVar::EnterSearch() {
02428 found_initial_solution_ = false;
02429 if (maximize_) {
02430 best_ = kint64min;
02431 } else {
02432 best_ = kint64max;
02433 }
02434 }
02435
02436 void OptimizeVar::RestartSearch() {
02437 ApplyBound();
02438 }
02439
02440 void OptimizeVar::ApplyBound() {
02441 if (found_initial_solution_) {
02442 if (maximize_) {
02443 var_->SetMin(best_ + step_);
02444 } else {
02445 var_->SetMax(best_ - step_);
02446 }
02447 }
02448 }
02449
02450 void OptimizeVar::RefuteDecision(Decision* const d) {
02451 ApplyBound();
02452 }
02453
02454 bool OptimizeVar::AcceptSolution() {
02455 const int64 val = var_->Value();
02456 if (!found_initial_solution_) {
02457 return true;
02458 } else {
02459
02460
02461
02462 return (maximize_ && val > best_) || (!maximize_ && val < best_);
02463 }
02464 }
02465
02466 bool OptimizeVar::AtSolution() {
02467 int64 val = var_->Value();
02468 if (maximize_) {
02469 CHECK(!found_initial_solution_ || val > best_);
02470 best_ = val;
02471 } else {
02472 CHECK(!found_initial_solution_ || val < best_);
02473 best_ = val;
02474 }
02475 found_initial_solution_ = true;
02476 return true;
02477 }
02478
02479 string OptimizeVar::Print() const {
02480 return StringPrintf("objective value = %" GG_LL_FORMAT "d, ", var_->Value());
02481 }
02482
02483 string OptimizeVar::DebugString() const {
02484 string out;
02485 if (maximize_) {
02486 out = "MaximizeVar(";
02487 } else {
02488 out = "MinimizeVar(";
02489 }
02490 StringAppendF(&out, "%s, step = %" GG_LL_FORMAT
02491 "d, best = %" GG_LL_FORMAT "d)",
02492 var_->DebugString().c_str(), step_, best_);
02493 return out;
02494 }
02495
02496 void OptimizeVar::Accept(ModelVisitor* const visitor) const {
02497 visitor->BeginVisitExtension(ModelVisitor::kObjectiveExtension);
02498 visitor->VisitIntegerArgument(ModelVisitor::kMaximizeArgument, maximize_);
02499 visitor->VisitIntegerArgument(ModelVisitor::kStepArgument, step_);
02500 visitor->VisitIntegerExpressionArgument(ModelVisitor::kExpressionArgument,
02501 var_);
02502 visitor->EndVisitExtension(ModelVisitor::kObjectiveExtension);
02503 }
02504
02505 OptimizeVar* Solver::MakeMinimize(IntVar* const v, int64 step) {
02506 return RevAlloc(new OptimizeVar(this, false, v, step));
02507 }
02508
02509 OptimizeVar* Solver::MakeMaximize(IntVar* const v, int64 step) {
02510 return RevAlloc(new OptimizeVar(this, true, v, step));
02511 }
02512
02513 OptimizeVar* Solver::MakeOptimize(bool maximize, IntVar* const v, int64 step) {
02514 return RevAlloc(new OptimizeVar(this, maximize, v, step));
02515 }
02516
02517 namespace {
02518 class WeightedOptimizeVar: public OptimizeVar {
02519 public:
02520 WeightedOptimizeVar(Solver* solver,
02521 bool maximize,
02522 const std::vector<IntVar*>& sub_objectives,
02523 const std::vector<int64>& weights,
02524 int64 step)
02525 : OptimizeVar(solver,
02526 maximize,
02527 solver->MakeScalProd(sub_objectives, weights)->Var(),
02528 step),
02529 size_(weights.size()) {
02530 CHECK_EQ(sub_objectives.size(), weights.size());
02531 sub_objectives_.reset(new IntVar*[size_]);
02532 memcpy(sub_objectives_.get(),
02533 sub_objectives.data(), size_ * sizeof(*sub_objectives.data()));
02534 weights_.reset(new int64[size_]);
02535 memcpy(weights_.get(),
02536 weights.data(), size_ * sizeof(*weights.data()));
02537 }
02538
02539 WeightedOptimizeVar(Solver* solver,
02540 bool maximize,
02541 const std::vector<IntVar*>& sub_objectives,
02542 const std::vector<int>& weights,
02543 int64 step)
02544 : OptimizeVar(solver,
02545 maximize,
02546 solver->MakeScalProd(sub_objectives, weights)->Var(),
02547 step),
02548 size_(weights.size()) {
02549 CHECK_EQ(sub_objectives.size(), weights.size());
02550 sub_objectives_.reset(new IntVar*[size_]);
02551 memcpy(sub_objectives_.get(),
02552 sub_objectives.data(), size_ * sizeof(*sub_objectives.data()));
02553 weights_.reset(new int64[size_]);
02554 for (int i = 0; i < size_; ++i) {
02555 weights_[i] = weights[i];
02556 }
02557 }
02558
02559 virtual ~WeightedOptimizeVar() {}
02560 virtual string Print() const;
02561
02562 private:
02563 const int64 size_;
02564 scoped_array<IntVar*> sub_objectives_;
02565 scoped_array<int64> weights_;
02566
02567 DISALLOW_COPY_AND_ASSIGN(WeightedOptimizeVar);
02568 };
02569
02570 string WeightedOptimizeVar::Print() const {
02571 string result(OptimizeVar::Print());
02572 StringAppendF(&result, "\nWeighted Objective:\n");
02573 for (int i = 0; i < size_; ++i) {
02574 StringAppendF(&result, "Variable %s,\tvalue %lld,\tweight %lld\n",
02575 sub_objectives_[i]->name().c_str(),
02576 sub_objectives_[i]->Value(),
02577 weights_[i]);
02578 }
02579 return result;
02580 }
02581 }
02582
02583 OptimizeVar* Solver::MakeWeightedOptimize(bool maximize,
02584 const std::vector<IntVar*>& sub_objectives,
02585 const std::vector<int64>& weights,
02586 int64 step) {
02587 return RevAlloc(new WeightedOptimizeVar(this,
02588 maximize,
02589 sub_objectives, weights,
02590 step));
02591 }
02592
02593 OptimizeVar* Solver::MakeWeightedMinimize(const std::vector<IntVar*>& sub_objectives,
02594 const std::vector<int64>& weights,
02595 int64 step) {
02596 return RevAlloc(new WeightedOptimizeVar(this,
02597 false,
02598 sub_objectives, weights,
02599 step));
02600 }
02601
02602 OptimizeVar* Solver::MakeWeightedMaximize(const std::vector<IntVar*>& sub_objectives,
02603 const std::vector<int64>& weights,
02604 int64 step) {
02605 return RevAlloc(new WeightedOptimizeVar(this,
02606 true,
02607 sub_objectives, weights,
02608 step));
02609 }
02610
02611 OptimizeVar* Solver::MakeWeightedOptimize(bool maximize,
02612 const std::vector<IntVar*>& sub_objectives,
02613 const std::vector<int>& weights,
02614 int64 step) {
02615 return RevAlloc(new WeightedOptimizeVar(this,
02616 maximize,
02617 sub_objectives, weights,
02618 step));
02619 }
02620
02621 OptimizeVar* Solver::MakeWeightedMinimize(const std::vector<IntVar*>& sub_objectives,
02622 const std::vector<int>& weights,
02623 int64 step) {
02624 return RevAlloc(new WeightedOptimizeVar(this,
02625 false,
02626 sub_objectives, weights,
02627 step));
02628 }
02629
02630 OptimizeVar* Solver::MakeWeightedMaximize(const std::vector<IntVar*>& sub_objectives,
02631 const std::vector<int>& weights,
02632 int64 step) {
02633 return RevAlloc(new WeightedOptimizeVar(this,
02634 true,
02635 sub_objectives, weights,
02636 step));
02637 }
02638
02639
02640
02641
02642 namespace {
02643 class Metaheuristic : public SearchMonitor {
02644 public:
02645 Metaheuristic(Solver* const solver,
02646 bool maximize,
02647 IntVar* objective,
02648 int64 step);
02649 virtual ~Metaheuristic() {}
02650
02651 virtual bool AtSolution();
02652 virtual void EnterSearch();
02653 virtual void RefuteDecision(Decision* const d);
02654
02655 protected:
02656 IntVar* const objective_;
02657 int64 step_;
02658 int64 current_;
02659 int64 best_;
02660 bool maximize_;
02661 };
02662
02663 Metaheuristic::Metaheuristic(Solver* const solver,
02664 bool maximize,
02665 IntVar* objective,
02666 int64 step)
02667 : SearchMonitor(solver),
02668 objective_(objective),
02669 step_(step),
02670 current_(kint64max),
02671 best_(kint64max),
02672 maximize_(maximize) {}
02673
02674 bool Metaheuristic::AtSolution() {
02675 current_ = objective_->Value();
02676 if (maximize_) {
02677 best_ = std::max(current_, best_);
02678 } else {
02679 best_ = std::min(current_, best_);
02680 }
02681 return true;
02682 }
02683
02684 void Metaheuristic::EnterSearch() {
02685 if (maximize_) {
02686 best_ = objective_->Min();
02687 current_ = kint64min;
02688 } else {
02689 best_ = objective_->Max();
02690 current_ = kint64max;
02691 }
02692 }
02693
02694 void Metaheuristic::RefuteDecision(Decision* d) {
02695 if (maximize_) {
02696 if (objective_->Max() < best_ + step_) {
02697 solver()->Fail();
02698 }
02699 } else if (objective_->Min() > best_ - step_) {
02700 solver()->Fail();
02701 }
02702 }
02703
02704
02705
02706 class TabuSearch : public Metaheuristic {
02707 public:
02708 TabuSearch(Solver* const s,
02709 bool maximize,
02710 IntVar* objective,
02711 int64 step,
02712 const IntVar* const* vars,
02713 int size,
02714 int64 keep_tenure,
02715 int64 forbid_tenure,
02716 double tabu_factor);
02717 virtual ~TabuSearch() {}
02718 virtual void EnterSearch();
02719 virtual void ApplyDecision(Decision* d);
02720 virtual bool AtSolution();
02721 virtual bool LocalOptimum();
02722 virtual void AcceptNeighbor();
02723 virtual string DebugString() const {
02724 return "Tabu Search";
02725 }
02726
02727 private:
02728 struct VarValue {
02729 VarValue(IntVar* const var, int64 value, int64 stamp)
02730 : var_(var), value_(value), stamp_(stamp) {}
02731 IntVar* const var_;
02732 const int64 value_;
02733 const int64 stamp_;
02734 };
02735 typedef std::list<VarValue> TabuList;
02736
02737 void AgeList(int64 tenure, TabuList* list);
02738 void AgeLists();
02739
02740 scoped_array<IntVar*> vars_;
02741 const int64 size_;
02742 Assignment assignment_;
02743 int64 last_;
02744 TabuList keep_tabu_list_;
02745 int64 keep_tenure_;
02746 TabuList forbid_tabu_list_;
02747 int64 forbid_tenure_;
02748 double tabu_factor_;
02749 int64 stamp_;
02750 bool found_initial_solution_;
02751 DISALLOW_COPY_AND_ASSIGN(TabuSearch);
02752 };
02753
02754 TabuSearch::TabuSearch(Solver* const s,
02755 bool maximize,
02756 IntVar* objective,
02757 int64 step,
02758 const IntVar* const* vars,
02759 int size,
02760 int64 keep_tenure,
02761 int64 forbid_tenure,
02762 double tabu_factor)
02763 : Metaheuristic(s, maximize, objective, step),
02764 size_(size),
02765 assignment_(s),
02766 last_(kint64max),
02767 keep_tenure_(keep_tenure),
02768 forbid_tenure_(forbid_tenure),
02769 tabu_factor_(tabu_factor),
02770 stamp_(0),
02771 found_initial_solution_(false) {
02772 CHECK_GE(size_, 0);
02773 if (size_ > 0) {
02774 vars_.reset(new IntVar*[size_]);
02775 memcpy(vars_.get(), vars, size_ * sizeof(*vars));
02776 assignment_.Add(vars_.get(), size);
02777 }
02778 }
02779
02780 void TabuSearch::EnterSearch() {
02781 Metaheuristic::EnterSearch();
02782 found_initial_solution_ = false;
02783 }
02784
02785 void TabuSearch::ApplyDecision(Decision* const d) {
02786 Solver* const s = solver();
02787 if (d == s->balancing_decision()) {
02788 return;
02789 }
02790
02791
02792 IntVar* aspiration = s->MakeBoolVar();
02793 if (maximize_) {
02794 s->AddConstraint(s->MakeIsGreaterOrEqualCstCt(objective_,
02795 best_ + step_,
02796 aspiration));
02797 } else {
02798 s->AddConstraint(s->MakeIsLessOrEqualCstCt(objective_,
02799 best_ - step_,
02800 aspiration));
02801 }
02802
02803
02804
02805
02806
02807
02808
02809 std::vector<IntVar*> tabu_vars;
02810 for (ConstIter<TabuList > it(keep_tabu_list_); !it.at_end(); ++it) {
02811 IntVar* tabu_var = s->MakeBoolVar();
02812 Constraint* keep_cst =
02813 s->MakeIsEqualCstCt((*it).var_, (*it).value_, tabu_var);
02814 s->AddConstraint(keep_cst);
02815 tabu_vars.push_back(tabu_var);
02816 }
02817 for (ConstIter<TabuList > it(forbid_tabu_list_); !it.at_end(); ++it) {
02818 IntVar* tabu_var = s->MakeBoolVar();
02819 Constraint* forbid_cst =
02820 s->MakeIsDifferentCstCt((*it).var_, (*it).value_, tabu_var);
02821 s->AddConstraint(forbid_cst);
02822 tabu_vars.push_back(tabu_var);
02823 }
02824 if (tabu_vars.size() > 0) {
02825 IntVar* tabu = s->MakeBoolVar();
02826 s->AddConstraint(s->MakeIsGreaterOrEqualCstCt(s->MakeSum(tabu_vars)->Var(),
02827 tabu_vars.size() *
02828 tabu_factor_,
02829 tabu));
02830 s->AddConstraint(s->MakeGreaterOrEqual(s->MakeSum(aspiration, tabu), 1LL));
02831 }
02832
02833
02834 if (maximize_) {
02835 const int64 bound = (current_ > kint64min) ? current_ + step_ : current_;
02836 s->AddConstraint(s->MakeGreaterOrEqual(objective_, bound));
02837 } else {
02838 const int64 bound = (current_ < kint64max) ? current_ - step_ : current_;
02839 s->AddConstraint(s->MakeLessOrEqual(objective_, bound));
02840 }
02841
02842
02843 if (found_initial_solution_) {
02844 s->AddConstraint(s->MakeNonEquality(objective_, last_));
02845 }
02846 }
02847
02848 bool TabuSearch::AtSolution() {
02849 if (!Metaheuristic::AtSolution()) {
02850 return false;
02851 }
02852 found_initial_solution_ = true;
02853 last_ = current_;
02854
02855
02856
02857 if (0 != stamp_) {
02858 for (int i = 0; i < size_; ++i) {
02859 IntVar* const var = vars_[i];
02860 const int64 old_value = assignment_.Value(var);
02861 const int64 new_value = var->Value();
02862 if (old_value != new_value) {
02863 VarValue keep_value(var, new_value, stamp_);
02864 keep_tabu_list_.push_front(keep_value);
02865 VarValue forbid_value(var, old_value, stamp_);
02866 forbid_tabu_list_.push_front(forbid_value);
02867 }
02868 }
02869 }
02870 assignment_.Store();
02871
02872 return true;
02873 }
02874
02875 bool TabuSearch::LocalOptimum() {
02876 AgeLists();
02877 if (maximize_) {
02878 current_ = kint64min;
02879 } else {
02880 current_ = kint64max;
02881 }
02882 return true;
02883 }
02884
02885 void TabuSearch::AcceptNeighbor() {
02886 if (0 != stamp_) {
02887 AgeLists();
02888 }
02889 }
02890
02891 void TabuSearch::AgeList(int64 tenure, TabuList* list) {
02892 while (!list->empty() && list->back().stamp_ < stamp_ - tenure) {
02893 list->pop_back();
02894 }
02895 }
02896
02897 void TabuSearch::AgeLists() {
02898 AgeList(keep_tenure_, &keep_tabu_list_);
02899 AgeList(forbid_tenure_, &forbid_tabu_list_);
02900 ++stamp_;
02901 }
02902 }
02903
02904 SearchMonitor* Solver::MakeTabuSearch(bool maximize,
02905 IntVar* const v,
02906 int64 step,
02907 const std::vector<IntVar*>& vars,
02908 int64 keep_tenure,
02909 int64 forbid_tenure,
02910 double tabu_factor) {
02911 return RevAlloc(new TabuSearch(this,
02912 maximize,
02913 v,
02914 step,
02915 vars.data(),
02916 vars.size(),
02917 keep_tenure,
02918 forbid_tenure,
02919 tabu_factor));
02920 }
02921
02922 SearchMonitor* Solver::MakeTabuSearch(bool maximize,
02923 IntVar* const v,
02924 int64 step,
02925 const IntVar* const* vars,
02926 int size,
02927 int64 keep_tenure,
02928 int64 forbid_tenure,
02929 double tabu_factor) {
02930 return RevAlloc(new TabuSearch(this,
02931 maximize,
02932 v,
02933 step,
02934 vars,
02935 size,
02936 keep_tenure,
02937 forbid_tenure,
02938 tabu_factor));
02939 }
02940
02941
02942
02943 namespace {
02944 class SimulatedAnnealing : public Metaheuristic {
02945 public:
02946 SimulatedAnnealing(Solver* const s,
02947 bool maximize,
02948 IntVar* objective,
02949 int64 step,
02950 int64 initial_temperature);
02951 virtual ~SimulatedAnnealing() {}
02952 virtual void ApplyDecision(Decision* d);
02953 virtual bool LocalOptimum();
02954 virtual void AcceptNeighbor();
02955 virtual string DebugString() const {
02956 return "Simulated Annealing";
02957 }
02958
02959 private:
02960 float Temperature() const;
02961
02962 const int64 temperature0_;
02963 int64 iteration_;
02964 ACMRandom rand_;
02965 };
02966
02967 SimulatedAnnealing::SimulatedAnnealing(Solver* const s,
02968 bool maximize,
02969 IntVar* objective,
02970 int64 step,
02971 int64 initial_temperature)
02972 : Metaheuristic(s, maximize, objective, step),
02973 temperature0_(initial_temperature),
02974 iteration_(0),
02975 rand_(654) {}
02976
02977 void SimulatedAnnealing::ApplyDecision(Decision* const d) {
02978 Solver* const s = solver();
02979 if (d == s->balancing_decision()) {
02980 return;
02981 }
02982 #if defined(_MSC_VER)
02983 const int64 energy_bound = Temperature() * log(rand_.RndFloat()) / log(2.0L);
02984 #else
02985 const int64 energy_bound = Temperature() * log2(rand_.RndFloat());
02986 #endif
02987 if (maximize_) {
02988 const int64 bound =
02989 (current_ > kint64min) ? current_ + step_ + energy_bound : current_;
02990 s->AddConstraint(s->MakeGreaterOrEqual(objective_, bound));
02991 } else {
02992 const int64 bound =
02993 (current_ < kint64max) ? current_ - step_ - energy_bound : current_;
02994 s->AddConstraint(s->MakeLessOrEqual(objective_, bound));
02995 }
02996 }
02997
02998 bool SimulatedAnnealing::LocalOptimum() {
02999 if (maximize_) {
03000 current_ = kint64min;
03001 } else {
03002 current_ = kint64max;
03003 }
03004 ++iteration_;
03005 return Temperature() > 0;
03006 }
03007
03008 void SimulatedAnnealing::AcceptNeighbor() {
03009 if (iteration_ > 0) {
03010 ++iteration_;
03011 }
03012 }
03013
03014 float SimulatedAnnealing::Temperature() const {
03015 if (iteration_ > 0) {
03016 return (1.0 * temperature0_) / iteration_;
03017 } else {
03018 return 0.;
03019 }
03020 }
03021 }
03022
03023 SearchMonitor* Solver::MakeSimulatedAnnealing(bool maximize,
03024 IntVar* const v,
03025 int64 step,
03026 int64 initial_temperature) {
03027 return RevAlloc(new SimulatedAnnealing(this,
03028 maximize,
03029 v,
03030 step,
03031 initial_temperature));
03032 }
03033
03034
03035
03036 typedef std::pair<int64, int64> Arc;
03037
03038 namespace {
03039
03040
03041 class GuidedLocalSearchPenalties {
03042 public:
03043 virtual ~GuidedLocalSearchPenalties() {}
03044 virtual bool HasValues() const = 0;
03045 virtual void Increment(const Arc& arc) = 0;
03046 virtual int64 Value(const Arc& arc) const = 0;
03047 virtual void Reset() = 0;
03048 };
03049
03050
03051 class GuidedLocalSearchPenaltiesTable : public GuidedLocalSearchPenalties {
03052 public:
03053 explicit GuidedLocalSearchPenaltiesTable(int size);
03054 virtual ~GuidedLocalSearchPenaltiesTable() {}
03055 virtual bool HasValues() const { return has_values_; }
03056 virtual void Increment(const Arc& arc);
03057 virtual int64 Value(const Arc& arc) const;
03058 virtual void Reset();
03059
03060 private:
03061 std::vector<std::vector<int64> > penalties_;
03062 bool has_values_;
03063 };
03064
03065 GuidedLocalSearchPenaltiesTable::GuidedLocalSearchPenaltiesTable(int size)
03066 : penalties_(size), has_values_(false) {
03067 }
03068
03069 void GuidedLocalSearchPenaltiesTable::Increment(const Arc& arc) {
03070 std::vector<int64>& first_penalties = penalties_[arc.first];
03071 const int64 second = arc.second;
03072 if (second >= first_penalties.size()) {
03073 first_penalties.resize(second + 1, 0LL);
03074 }
03075 ++first_penalties[second];
03076 has_values_ = true;
03077 }
03078
03079 void GuidedLocalSearchPenaltiesTable::Reset() {
03080 has_values_ = false;
03081 for (int i = 0; i < penalties_.size(); ++i) {
03082 penalties_[i].clear();
03083 }
03084 }
03085
03086 int64 GuidedLocalSearchPenaltiesTable::Value(const Arc& arc) const {
03087 const std::vector<int64>& first_penalties = penalties_[arc.first];
03088 const int64 second = arc.second;
03089 if (second >= first_penalties.size()) {
03090 return 0LL;
03091 } else {
03092 return first_penalties[second];
03093 }
03094 }
03095
03096
03097
03098 class GuidedLocalSearchPenaltiesMap : public GuidedLocalSearchPenalties {
03099 public:
03100 explicit GuidedLocalSearchPenaltiesMap(int size);
03101 virtual ~GuidedLocalSearchPenaltiesMap() {}
03102 virtual bool HasValues() const { return (penalties_.size() != 0); }
03103 virtual void Increment(const Arc& arc);
03104 virtual int64 Value(const Arc& arc) const;
03105 virtual void Reset();
03106
03107 private:
03108 Bitmap penalized_;
03109 #if defined(_MSC_VER)
03110 hash_map<Arc, int64, PairInt64Hasher> penalties_;
03111 #else
03112 hash_map<Arc, int64> penalties_;
03113 #endif
03114 };
03115
03116 GuidedLocalSearchPenaltiesMap::GuidedLocalSearchPenaltiesMap(int size)
03117 : penalized_(size, false) {}
03118
03119 void GuidedLocalSearchPenaltiesMap::Increment(const Arc& arc) {
03120 ++penalties_[arc];
03121 penalized_.Set(arc.first, true);
03122 }
03123
03124 void GuidedLocalSearchPenaltiesMap::Reset() {
03125 penalties_.clear();
03126 penalized_.Clear();
03127 }
03128
03129 int64 GuidedLocalSearchPenaltiesMap::Value(const Arc& arc) const {
03130 if (penalized_.Get(arc.first)) {
03131 return FindWithDefault(penalties_, arc, 0LL);
03132 }
03133 return 0LL;
03134 }
03135
03136 class GuidedLocalSearch : public Metaheuristic {
03137 public:
03138 GuidedLocalSearch(Solver* const s,
03139 IntVar* objective,
03140 bool maximize,
03141 int64 step,
03142 const IntVar* const* vars,
03143 int size,
03144 double penalty_factor);
03145 virtual ~GuidedLocalSearch() {}
03146 virtual bool AcceptDelta(Assignment* delta, Assignment* deltadelta);
03147 virtual void ApplyDecision(Decision* d);
03148 virtual bool AtSolution();
03149 virtual void EnterSearch();
03150 virtual bool LocalOptimum();
03151 virtual int64 AssignmentElementPenalty(const Assignment& assignment,
03152 int index) = 0;
03153 virtual int64 AssignmentPenalty(const Assignment& assignment,
03154 int index,
03155 int64 next) = 0;
03156 virtual bool EvaluateElementValue(const Assignment::IntContainer& container,
03157 int64 index,
03158 int* container_index,
03159 int64* penalty) = 0;
03160 virtual IntExpr* MakeElementPenalty(int index) = 0;
03161 virtual string DebugString() const {
03162 return "Guided Local Search";
03163 }
03164
03165 protected:
03166 struct Comparator {
03167 bool operator() (const std::pair<Arc, double>& i,
03168 const std::pair<Arc, double>& j) {
03169 return i.second > j.second;
03170 }
03171 };
03172
03173 int64 Evaluate(const Assignment* delta,
03174 int64 current_penalty,
03175 const int64* const out_values,
03176 bool cache_delta_values);
03177
03178 IntVar* penalized_objective_;
03179 Assignment assignment_;
03180 int64 assignment_penalized_value_;
03181 int64 old_penalized_value_;
03182 scoped_array<IntVar*> vars_;
03183 const int64 size_;
03184 hash_map<const IntVar*, int64> indices_;
03185 const double penalty_factor_;
03186 scoped_ptr<GuidedLocalSearchPenalties> penalties_;
03187 scoped_array<int64> current_penalized_values_;
03188 scoped_array<int64> delta_cache_;
03189 bool incremental_;
03190 };
03191
03192 GuidedLocalSearch::GuidedLocalSearch(Solver* const s,
03193 IntVar* objective,
03194 bool maximize,
03195 int64 step,
03196 const IntVar* const* vars,
03197 int size,
03198 double penalty_factor)
03199 : Metaheuristic(s, maximize, objective, step),
03200 penalized_objective_(NULL),
03201 assignment_(s),
03202 assignment_penalized_value_(0),
03203 old_penalized_value_(0),
03204 size_(size),
03205 penalty_factor_(penalty_factor),
03206 incremental_(false) {
03207 DCHECK_GE(size_, 0);
03208 if (size_ > 0) {
03209 vars_.reset(new IntVar*[size_]);
03210 memcpy(vars_.get(), vars, size_ * sizeof(*vars));
03211 assignment_.Add(vars_.get(), size);
03212 current_penalized_values_.reset(new int64[size]);
03213 delta_cache_.reset(new int64[size]);
03214 memset(current_penalized_values_.get(), 0,
03215 size_ * sizeof(*current_penalized_values_.get()));
03216 }
03217 for (int i = 0; i < size; ++i) {
03218 indices_[vars_[i]] = i;
03219 }
03220 if (FLAGS_cp_use_sparse_gls_penalties) {
03221 penalties_.reset(new GuidedLocalSearchPenaltiesMap(size));
03222 } else {
03223 penalties_.reset(new GuidedLocalSearchPenaltiesTable(size));
03224 }
03225 }
03226
03227
03228
03229
03230
03231
03232
03233
03234 void GuidedLocalSearch::ApplyDecision(Decision* const d) {
03235 if (d == solver()->balancing_decision()) {
03236 return;
03237 }
03238 std::vector<IntVar*> elements;
03239 assignment_penalized_value_ = 0;
03240 if (penalties_->HasValues()) {
03241 for (int i = 0; i < size_; ++i) {
03242 IntExpr* expr = MakeElementPenalty(i);
03243 elements.push_back(expr->Var());
03244 const int64 penalty = AssignmentElementPenalty(assignment_, i);
03245 current_penalized_values_[i] = penalty;
03246 delta_cache_[i] = penalty;
03247 assignment_penalized_value_ += penalty;
03248 }
03249 old_penalized_value_ = assignment_penalized_value_;
03250 incremental_ = false;
03251 penalized_objective_ = solver()->MakeSum(elements)->Var();
03252 if (maximize_) {
03253 IntExpr* min_pen_exp = solver()->MakeDifference(current_ + step_,
03254 penalized_objective_);
03255 IntVar* min_exp = solver()->MakeMin(min_pen_exp, best_ + step_)->Var();
03256 solver()->AddConstraint(solver()->MakeGreaterOrEqual(objective_,
03257 min_exp));
03258 } else {
03259 IntExpr* max_pen_exp = solver()->MakeDifference(current_ - step_,
03260 penalized_objective_);
03261 IntVar* max_exp = solver()->MakeMax(max_pen_exp, best_ - step_)->Var();
03262 solver()->AddConstraint(solver()->MakeLessOrEqual(objective_, max_exp));
03263 }
03264 } else {
03265 penalized_objective_ = NULL;
03266 if (maximize_) {
03267 const int64 bound = (current_ > kint64min) ? current_ + step_ : current_;
03268 objective_->SetMin(bound);
03269 } else {
03270 const int64 bound = (current_ < kint64max) ? current_ - step_ : current_;
03271 objective_->SetMax(bound);
03272 }
03273 }
03274 }
03275
03276 bool GuidedLocalSearch::AtSolution() {
03277 if (!Metaheuristic::AtSolution()) {
03278 return false;
03279 }
03280 if (penalized_objective_ != NULL) {
03281 current_ += penalized_objective_->Value();
03282 }
03283 assignment_.Store();
03284 return true;
03285 }
03286
03287 void GuidedLocalSearch::EnterSearch() {
03288 Metaheuristic::EnterSearch();
03289 penalized_objective_ = NULL;
03290 assignment_penalized_value_ = 0;
03291 old_penalized_value_ = 0;
03292 memset(current_penalized_values_.get(), 0,
03293 size_ * sizeof(*current_penalized_values_.get()));
03294 penalties_->Reset();
03295 }
03296
03297
03298
03299 bool GuidedLocalSearch::AcceptDelta(Assignment* delta, Assignment* deltadelta) {
03300 if ((delta != NULL || deltadelta != NULL) && penalties_->HasValues()) {
03301 int64 penalty = 0;
03302 if (!deltadelta->Empty()) {
03303 if (!incremental_) {
03304 penalty = Evaluate(delta,
03305 assignment_penalized_value_,
03306 current_penalized_values_.get(),
03307 true);
03308 } else {
03309 penalty = Evaluate(deltadelta,
03310 old_penalized_value_,
03311 delta_cache_.get(),
03312 true);
03313 }
03314 incremental_ = true;
03315 } else {
03316 if (incremental_) {
03317 for (int i = 0; i < size_; ++i) {
03318 delta_cache_[i] = current_penalized_values_[i];
03319 }
03320 old_penalized_value_ = assignment_penalized_value_;
03321 }
03322 incremental_ = false;
03323 penalty = Evaluate(delta,
03324 assignment_penalized_value_,
03325 current_penalized_values_.get(),
03326 false);
03327 }
03328 old_penalized_value_ = penalty;
03329 if (!delta->HasObjective()) {
03330 delta->AddObjective(objective_);
03331 }
03332 if (delta->Objective() == objective_) {
03333 if (maximize_) {
03334 delta->SetObjectiveMin(std::max(std::min(current_ + step_ - penalty,
03335 best_ + step_),
03336 delta->ObjectiveMin()));
03337 } else {
03338 delta->SetObjectiveMax(std::min(std::max(current_ - step_ - penalty,
03339 best_ - step_),
03340 delta->ObjectiveMax()));
03341 }
03342 }
03343 }
03344 return true;
03345 }
03346
03347 int64 GuidedLocalSearch::Evaluate(const Assignment* delta,
03348 int64 current_penalty,
03349 const int64* const out_values,
03350 bool cache_delta_values) {
03351 int64 penalty = current_penalty;
03352 const Assignment::IntContainer& container = delta->IntVarContainer();
03353 const int size = container.Size();
03354 for (int i = 0; i < size; ++i) {
03355 const IntVarElement& new_element = container.Element(i);
03356 const IntVar* var = new_element.Var();
03357 int64 index = -1;
03358 if (FindCopy(indices_, var, &index)) {
03359 penalty -= out_values[index];
03360 int64 new_penalty = 0;
03361 if (EvaluateElementValue(container, index, &i, &new_penalty)) {
03362 penalty += new_penalty;
03363 if (cache_delta_values) {
03364 delta_cache_[index] = new_penalty;
03365 }
03366 }
03367 }
03368 }
03369 return penalty;
03370 }
03371
03372
03373
03374 bool GuidedLocalSearch::LocalOptimum() {
03375 std::vector<std::pair<Arc, double> > utility(size_);
03376 for (int i = 0; i < size_; ++i) {
03377 const int64 var_value = assignment_.Value(vars_[i]);
03378 const int64 value =
03379 (var_value != i) ? AssignmentPenalty(assignment_, i, var_value) : 0;
03380 const Arc arc(i, var_value);
03381 const int64 penalty = penalties_->Value(arc);
03382 utility[i] = std::pair<Arc, double>(arc, value / (penalty + 1.0));
03383 }
03384 Comparator comparator;
03385 std::stable_sort(utility.begin(), utility.end(), comparator);
03386 int64 utility_value = utility[0].second;
03387 penalties_->Increment(utility[0].first);
03388 for (int i = 1;
03389 i < utility.size() && utility_value == utility[i].second;
03390 ++i) {
03391 penalties_->Increment(utility[i].first);
03392 }
03393 if (maximize_) {
03394 current_ = kint64min;
03395 } else {
03396 current_ = kint64max;
03397 }
03398 return true;
03399 }
03400
03401 class BinaryGuidedLocalSearch : public GuidedLocalSearch {
03402 public:
03403 BinaryGuidedLocalSearch(Solver* const solver,
03404 IntVar* const objective,
03405 Solver::IndexEvaluator2* objective_function,
03406 bool maximize,
03407 int64 step,
03408 const IntVar* const* vars,
03409 int size,
03410 double penalty_factor);
03411 virtual ~BinaryGuidedLocalSearch() {}
03412 virtual IntExpr* MakeElementPenalty(int index);
03413 virtual int64 AssignmentElementPenalty(const Assignment& assignment,
03414 int index);
03415 virtual int64 AssignmentPenalty(const Assignment& assignment,
03416 int index,
03417 int64 next);
03418 virtual bool EvaluateElementValue(const Assignment::IntContainer& container,
03419 int64 index,
03420 int* container_index,
03421 int64* penalty);
03422
03423 private:
03424 int64 PenalizedValue(int64 i, int64 j);
03425 scoped_ptr<Solver::IndexEvaluator2> objective_function_;
03426 };
03427
03428 BinaryGuidedLocalSearch::BinaryGuidedLocalSearch(
03429 Solver* const solver,
03430 IntVar* const objective,
03431 Solver::IndexEvaluator2* objective_function,
03432 bool maximize,
03433 int64 step,
03434 const IntVar* const* vars,
03435 int size,
03436 double penalty_factor)
03437 : GuidedLocalSearch(
03438 solver, objective, maximize, step, vars, size, penalty_factor),
03439 objective_function_(objective_function) {
03440 objective_function_->CheckIsRepeatable();
03441 }
03442
03443 IntExpr* BinaryGuidedLocalSearch::MakeElementPenalty(int index) {
03444 return solver()->MakeElement(
03445 NewPermanentCallback(this,
03446 &BinaryGuidedLocalSearch::PenalizedValue,
03447 static_cast<int64>(index)),
03448 vars_[index]);
03449 }
03450
03451 int64 BinaryGuidedLocalSearch::AssignmentElementPenalty(
03452 const Assignment& assignment,
03453 int index) {
03454 return PenalizedValue(index, assignment.Value(vars_[index]));
03455 }
03456
03457 int64 BinaryGuidedLocalSearch::AssignmentPenalty(
03458 const Assignment& assignment,
03459 int index,
03460 int64 next) {
03461 return objective_function_->Run(index, next);
03462 }
03463
03464 bool BinaryGuidedLocalSearch::EvaluateElementValue(
03465 const Assignment::IntContainer& container,
03466 int64 index,
03467 int* container_index,
03468 int64* penalty) {
03469 const IntVarElement& element = container.Element(*container_index);
03470 if (element.Activated()) {
03471 *penalty = PenalizedValue(index, element.Value());
03472 return true;
03473 }
03474 return false;
03475 }
03476
03477
03478 int64 BinaryGuidedLocalSearch::PenalizedValue(int64 i, int64 j) {
03479 const Arc arc(i, j);
03480 const int64 penalty = penalties_->Value(arc);
03481 if (penalty != 0) {
03482 const int64 penalized_value =
03483 penalty_factor_ * penalty * objective_function_->Run(i, j);
03484 if (maximize_) {
03485 return -penalized_value;
03486 } else {
03487 return penalized_value;
03488 }
03489 } else {
03490 return 0;
03491 }
03492 }
03493
03494 class TernaryGuidedLocalSearch : public GuidedLocalSearch {
03495 public:
03496 TernaryGuidedLocalSearch(Solver* const solver,
03497 IntVar* const objective,
03498 Solver::IndexEvaluator3* objective_function,
03499 bool maximize,
03500 int64 step,
03501 const IntVar* const* vars,
03502 const IntVar* const* secondary_vars,
03503 int size,
03504 double penalty_factor);
03505 virtual ~TernaryGuidedLocalSearch() {}
03506 virtual IntExpr* MakeElementPenalty(int index);
03507 virtual int64 AssignmentElementPenalty(const Assignment& assignment,
03508 int index);
03509 virtual int64 AssignmentPenalty(const Assignment& assignment,
03510 int index,
03511 int64 next);
03512 virtual bool EvaluateElementValue(const Assignment::IntContainer& container,
03513 int64 index,
03514 int* container_index,
03515 int64* penalty);
03516
03517 private:
03518 int64 PenalizedValue(int64 i, int64 j, int64 k);
03519 int64 GetAssignmentSecondaryValue(const Assignment::IntContainer& container,
03520 int index,
03521 int* container_index) const;
03522
03523 scoped_array<IntVar*> secondary_vars_;
03524 scoped_ptr<Solver::IndexEvaluator3> objective_function_;
03525 };
03526
03527 TernaryGuidedLocalSearch::TernaryGuidedLocalSearch(
03528 Solver* const solver,
03529 IntVar* const objective,
03530 Solver::IndexEvaluator3* objective_function,
03531 bool maximize,
03532 int64 step,
03533 const IntVar* const* vars,
03534 const IntVar* const* secondary_vars,
03535 int size,
03536 double penalty_factor)
03537 : GuidedLocalSearch(
03538 solver, objective, maximize, step, vars, size, penalty_factor),
03539 objective_function_(objective_function) {
03540 objective_function_->CheckIsRepeatable();
03541 CHECK_GE(size_, 0);
03542 if (size_ > 0) {
03543 secondary_vars_.reset(new IntVar*[size_]);
03544 memcpy(secondary_vars_.get(),
03545 secondary_vars, size_ * sizeof(*secondary_vars));
03546 assignment_.Add(secondary_vars_.get(), size_);
03547 }
03548 }
03549
03550 IntExpr* TernaryGuidedLocalSearch::MakeElementPenalty(int index) {
03551 return solver()->MakeElement(
03552 NewPermanentCallback(this,
03553 &TernaryGuidedLocalSearch::PenalizedValue,
03554 static_cast<int64>(index)),
03555 vars_[index],
03556 secondary_vars_[index]);
03557 }
03558
03559 int64 TernaryGuidedLocalSearch::AssignmentElementPenalty(
03560 const Assignment& assignment,
03561 int index) {
03562 return PenalizedValue(index,
03563 assignment.Value(vars_[index]),
03564 assignment.Value(secondary_vars_[index]));
03565 }
03566
03567 int64 TernaryGuidedLocalSearch::AssignmentPenalty(
03568 const Assignment& assignment,
03569 int index,
03570 int64 next) {
03571 return objective_function_->Run(index,
03572 next,
03573 assignment.Value(secondary_vars_[index]));
03574 }
03575
03576 bool TernaryGuidedLocalSearch::EvaluateElementValue(
03577 const Assignment::IntContainer& container,
03578 int64 index,
03579 int* container_index,
03580 int64* penalty) {
03581 const IntVarElement& element = container.Element(*container_index);
03582 if (element.Activated()) {
03583 *penalty = PenalizedValue(index,
03584 element.Value(),
03585 GetAssignmentSecondaryValue(container,
03586 index,
03587 container_index));
03588 return true;
03589 }
03590 return false;
03591 }
03592
03593
03594 int64 TernaryGuidedLocalSearch::PenalizedValue(int64 i, int64 j, int64 k) {
03595 const Arc arc(i, j);
03596 const int64 penalty = penalties_->Value(arc);
03597 if (penalty != 0) {
03598 const int64 penalized_value =
03599 penalty_factor_ * penalty * objective_function_->Run(i, j, k);
03600 if (maximize_) {
03601 return -penalized_value;
03602 } else {
03603 return penalized_value;
03604 }
03605 } else {
03606 return 0;
03607 }
03608 }
03609
03610 int64 TernaryGuidedLocalSearch::GetAssignmentSecondaryValue(
03611 const Assignment::IntContainer& container,
03612 int index,
03613 int* container_index) const {
03614 const IntVar* secondary_var = secondary_vars_[index];
03615 int hint_index = *container_index + 1;
03616 if (hint_index > 0 && hint_index < container.Size()
03617 && secondary_var == container.Element(hint_index).Var()) {
03618 *container_index = hint_index;
03619 return container.Element(hint_index).Value();
03620 } else {
03621 return container.Element(secondary_var).Value();
03622 }
03623 }
03624 }
03625
03626 SearchMonitor* Solver::MakeGuidedLocalSearch(
03627 bool maximize,
03628 IntVar* const objective,
03629 ResultCallback2<int64, int64, int64>* objective_function,
03630 int64 step,
03631 const std::vector<IntVar*>& vars,
03632 double penalty_factor) {
03633 return MakeGuidedLocalSearch(maximize,
03634 objective,
03635 objective_function,
03636 step,
03637 vars.data(),
03638 vars.size(),
03639 penalty_factor);
03640 }
03641
03642 SearchMonitor* Solver::MakeGuidedLocalSearch(
03643 bool maximize,
03644 IntVar* const objective,
03645 ResultCallback2<int64, int64, int64>* objective_function,
03646 int64 step,
03647 const IntVar* const* vars,
03648 int size,
03649 double penalty_factor) {
03650 return RevAlloc(new BinaryGuidedLocalSearch(this,
03651 objective,
03652 objective_function,
03653 maximize,
03654 step,
03655 vars,
03656 size,
03657 penalty_factor));
03658 }
03659
03660 SearchMonitor* Solver::MakeGuidedLocalSearch(
03661 bool maximize,
03662 IntVar* const objective,
03663 ResultCallback3<int64, int64, int64, int64>* objective_function,
03664 int64 step,
03665 const std::vector<IntVar*>& vars,
03666 const std::vector<IntVar*>& secondary_vars,
03667 double penalty_factor) {
03668 return MakeGuidedLocalSearch(maximize,
03669 objective,
03670 objective_function,
03671 step,
03672 vars.data(),
03673 secondary_vars.data(),
03674 vars.size(),
03675 penalty_factor);
03676 }
03677
03678 SearchMonitor* Solver::MakeGuidedLocalSearch(
03679 bool maximize,
03680 IntVar* const objective,
03681 ResultCallback3<int64, int64, int64, int64>* objective_function,
03682 int64 step,
03683 const IntVar* const* vars,
03684 const IntVar* const* secondary_vars,
03685 int size,
03686 double penalty_factor) {
03687 return RevAlloc(new TernaryGuidedLocalSearch(this,
03688 objective,
03689 objective_function,
03690 maximize,
03691 step,
03692 vars,
03693 secondary_vars,
03694 size,
03695 penalty_factor));
03696 }
03697
03698
03699
03700
03701
03702 SearchLimit::~SearchLimit() {}
03703
03704 void SearchLimit::EnterSearch() {
03705 crossed_ = false;
03706 Init();
03707 }
03708
03709 void SearchLimit::BeginNextDecision(DecisionBuilder* const b) {
03710 PeriodicCheck();
03711 }
03712
03713 void SearchLimit::RefuteDecision(Decision* const d) {
03714 PeriodicCheck();
03715 }
03716
03717 void SearchLimit::PeriodicCheck() {
03718 if (crossed_ || Check()) {
03719 crossed_ = true;
03720 solver()->Fail();
03721 }
03722 }
03723
03724 namespace {
03725
03726
03727
03728
03729 class RegularLimit : public SearchLimit {
03730 public:
03731 RegularLimit(Solver* const s,
03732 int64 time,
03733 int64 branches,
03734 int64 failures,
03735 int64 solutions,
03736 bool smart_time_check,
03737 bool cumulative);
03738 virtual ~RegularLimit();
03739 virtual void Copy(const SearchLimit* const limit);
03740 virtual SearchLimit* MakeClone() const;
03741 virtual bool Check();
03742 virtual void Init();
03743 virtual void ExitSearch();
03744 void UpdateLimits(int64 time,
03745 int64 branches,
03746 int64 failures,
03747 int64 solutions);
03748 int64 wall_time() { return wall_time_; }
03749 virtual int ProgressPercent();
03750 virtual string DebugString() const;
03751
03752 void Accept(ModelVisitor* const visitor) const {
03753 visitor->BeginVisitExtension(ModelVisitor::kSearchLimitExtension);
03754 visitor->VisitIntegerArgument(ModelVisitor::kTimeLimitArgument, wall_time_);
03755 visitor->VisitIntegerArgument(ModelVisitor::kBranchesLimitArgument,
03756 branches_);
03757 visitor->VisitIntegerArgument(ModelVisitor::kFailuresLimitArgument,
03758 failures_);
03759 visitor->VisitIntegerArgument(ModelVisitor::kSolutionLimitArgument,
03760 solutions_);
03761 visitor->VisitIntegerArgument(ModelVisitor::kSmartTimeCheckArgument,
03762 smart_time_check_);
03763 visitor->VisitIntegerArgument(ModelVisitor::kCumulativeArgument,
03764 cumulative_);
03765 visitor->EndVisitExtension(ModelVisitor::kObjectiveExtension);
03766 }
03767
03768 private:
03769 bool CheckTime();
03770 int64 TimeDelta();
03771 static int64 GetPercent(int value, int offset, int total) {
03772 return (total > 0 && total < kint64max) ?
03773 100 * (value - offset) / total : -1;
03774 }
03775
03776 int64 wall_time_;
03777 int64 wall_time_offset_;
03778 int64 last_time_delta_;
03779 int64 check_count_;
03780 int64 next_check_;
03781 bool smart_time_check_;
03782 int64 branches_;
03783 int64 branches_offset_;
03784 int64 failures_;
03785 int64 failures_offset_;
03786 int64 solutions_;
03787 int64 solutions_offset_;
03788
03789
03790
03791
03792
03793
03794
03795 bool cumulative_;
03796 };
03797
03798 RegularLimit::RegularLimit(Solver* const s,
03799 int64 time,
03800 int64 branches,
03801 int64 failures,
03802 int64 solutions,
03803 bool smart_time_check,
03804 bool cumulative)
03805 : SearchLimit(s),
03806 wall_time_(time),
03807 wall_time_offset_(0),
03808 last_time_delta_(-1),
03809 check_count_(0),
03810 next_check_(0),
03811 smart_time_check_(smart_time_check),
03812 branches_(branches),
03813 branches_offset_(0),
03814 failures_(failures),
03815 failures_offset_(0),
03816 solutions_(solutions),
03817 solutions_offset_(0),
03818 cumulative_(cumulative) {}
03819
03820 RegularLimit::~RegularLimit() {}
03821
03822 void RegularLimit::Copy(const SearchLimit* const limit) {
03823 const RegularLimit* const regular =
03824 reinterpret_cast<const RegularLimit* const>(limit);
03825 wall_time_ = regular->wall_time_;
03826 branches_ = regular->branches_;
03827 failures_ = regular->failures_;
03828 solutions_ = regular->solutions_;
03829 smart_time_check_ = regular->smart_time_check_;
03830 cumulative_ = regular->cumulative_;
03831 }
03832
03833 SearchLimit* RegularLimit::MakeClone() const {
03834 Solver* const s = solver();
03835 return s->MakeLimit(wall_time_,
03836 branches_,
03837 failures_,
03838 solutions_,
03839 smart_time_check_);
03840 }
03841
03842 bool RegularLimit::Check() {
03843 Solver* const s = solver();
03844
03845 return s->branches() - branches_offset_ >= branches_ ||
03846 s->failures() - failures_offset_ >= failures_ ||
03847 CheckTime() ||
03848 s->solutions() - solutions_offset_ >= solutions_;
03849 }
03850
03851 int RegularLimit::ProgressPercent() {
03852 Solver* const s = solver();
03853 int64 progress = GetPercent(s->branches(), branches_offset_, branches_);
03854 progress = std::max(progress,
03855 GetPercent(s->failures(), failures_offset_, failures_));
03856 progress =
03857 std::max(progress,
03858 GetPercent(s->solutions(), solutions_offset_, solutions_));
03859 if (wall_time_ < kint64max) {
03860 progress = std::max(progress, (100 * TimeDelta()) / wall_time_);
03861 }
03862 return progress;
03863 }
03864
03865 void RegularLimit::Init() {
03866 Solver* const s = solver();
03867 branches_offset_ = s->branches();
03868 failures_offset_ = s->failures();
03869 wall_time_offset_ = s->wall_time();
03870 last_time_delta_ = -1;
03871 solutions_offset_ = s->solutions();
03872 check_count_ = 0;
03873 next_check_ = 0;
03874 }
03875
03876 void RegularLimit::ExitSearch() {
03877 if (cumulative_) {
03878
03879 Solver* const s = solver();
03880 branches_ -= s->branches() - branches_offset_;
03881 failures_ -= s->failures() - failures_offset_;
03882 wall_time_ -= s->wall_time() - wall_time_offset_;
03883 solutions_ -= s->solutions() - solutions_offset_;
03884 }
03885 }
03886
03887 void RegularLimit::UpdateLimits(int64 time,
03888 int64 branches,
03889 int64 failures,
03890 int64 solutions) {
03891 wall_time_ = time;
03892 branches_ = branches;
03893 failures_ = failures;
03894 solutions_ = solutions;
03895 }
03896
03897 string RegularLimit::DebugString() const {
03898 return StringPrintf("RegularLimit(crossed = %i, wall_time = %"
03899 GG_LL_FORMAT "d, "
03900 "branches = %" GG_LL_FORMAT
03901 "d, failures = %" GG_LL_FORMAT
03902 "d, solutions = %" GG_LL_FORMAT
03903 "d cumulative = %s",
03904 crossed(), wall_time_, branches_, failures_, solutions_,
03905 (cumulative_? "true":"false"));
03906 }
03907
03908 bool RegularLimit::CheckTime() {
03909 return TimeDelta() >= wall_time_;
03910 }
03911
03912 int64 RegularLimit::TimeDelta() {
03913 const int64 kMaxSkip = 100;
03914 const int64 kCheckWarmupIterations = 100;
03915 ++check_count_;
03916 if (wall_time_ != kint64max && next_check_ <= check_count_) {
03917 Solver* const s = solver();
03918 int64 time_delta = s->wall_time() - wall_time_offset_;
03919 if (smart_time_check_
03920 && check_count_ > kCheckWarmupIterations
03921 && time_delta > 0) {
03922 int64 approximate_calls = (wall_time_ * check_count_) / time_delta;
03923 next_check_ = check_count_ + std::min(kMaxSkip, approximate_calls);
03924 }
03925 last_time_delta_ = time_delta;
03926 }
03927 return last_time_delta_;
03928 }
03929 }
03930
03931 SearchLimit* Solver::MakeTimeLimit(int64 time) {
03932 return MakeLimit(time, kint64max, kint64max, kint64max);
03933 }
03934
03935 SearchLimit* Solver::MakeBranchesLimit(int64 branches) {
03936 return MakeLimit(kint64max, branches, kint64max, kint64max);
03937 }
03938
03939 SearchLimit* Solver::MakeFailuresLimit(int64 failures) {
03940 return MakeLimit(kint64max, kint64max, failures, kint64max);
03941 }
03942
03943 SearchLimit* Solver::MakeSolutionsLimit(int64 solutions) {
03944 return MakeLimit(kint64max, kint64max, kint64max, solutions);
03945 }
03946
03947 SearchLimit* Solver::MakeLimit(int64 time,
03948 int64 branches,
03949 int64 failures,
03950 int64 solutions) {
03951 return MakeLimit(time, branches, failures, solutions, false);
03952 }
03953
03954 SearchLimit* Solver::MakeLimit(int64 time,
03955 int64 branches,
03956 int64 failures,
03957 int64 solutions,
03958 bool smart_time_check) {
03959 return MakeLimit(
03960 time, branches, failures, solutions, smart_time_check, false);
03961 }
03962
03963 SearchLimit* Solver::MakeLimit(int64 time,
03964 int64 branches,
03965 int64 failures,
03966 int64 solutions,
03967 bool smart_time_check,
03968 bool cumulative) {
03969 return RevAlloc(new RegularLimit(this,
03970 time,
03971 branches,
03972 failures,
03973 solutions,
03974 smart_time_check,
03975 cumulative));
03976 }
03977
03978 SearchLimit* Solver::MakeLimit(
03979 const SearchLimitProto& proto) {
03980 return MakeLimit(proto.time(),
03981 proto.branches(),
03982 proto.failures(),
03983 proto.solutions(),
03984 proto.smart_time_check(),
03985 proto.cumulative());
03986 }
03987
03988
03989 namespace {
03990 class ORLimit : public SearchLimit {
03991 public:
03992 ORLimit(SearchLimit* limit_1,
03993 SearchLimit* limit_2)
03994 : SearchLimit(limit_1->solver()),
03995 limit_1_(limit_1),
03996 limit_2_(limit_2) {
03997 CHECK_NOTNULL(limit_1);
03998 CHECK_NOTNULL(limit_2);
03999 CHECK_EQ(limit_1->solver(), limit_2->solver())
04000 << "Illegal arguments: cannot combines limits that belong to different "
04001 << "solvers, because the reversible allocations could delete one and "
04002 << "not the other.";
04003 }
04004
04005 virtual bool Check() {
04006
04007
04008 const bool check_1 = limit_1_->Check();
04009 const bool check_2 = limit_2_->Check();
04010 return check_1 || check_2;
04011 }
04012
04013 virtual void Init() {
04014 limit_1_->Init();
04015 limit_2_->Init();
04016 }
04017
04018 virtual void Copy(const SearchLimit* const limit) {
04019 LOG(FATAL) << "Not implemented.";
04020 }
04021
04022 virtual SearchLimit* MakeClone() const {
04023
04024 return solver()->MakeLimit(limit_1_->MakeClone(), limit_2_->MakeClone());
04025 }
04026
04027 virtual void EnterSearch() {
04028 limit_1_->EnterSearch();
04029 limit_2_->EnterSearch();
04030 }
04031 virtual void BeginNextDecision(DecisionBuilder* const b) {
04032 limit_1_->BeginNextDecision(b);
04033 limit_2_->BeginNextDecision(b);
04034 }
04035 virtual void PeriodicCheck() {
04036 limit_1_->PeriodicCheck();
04037 limit_2_->PeriodicCheck();
04038 }
04039 virtual void RefuteDecision(Decision* const d) {
04040 limit_1_->RefuteDecision(d);
04041 limit_2_->RefuteDecision(d);
04042 }
04043 virtual string DebugString() const {
04044 return StrCat("OR limit (", limit_1_->DebugString(),
04045 " OR ", limit_2_->DebugString(), ")");
04046 }
04047
04048 private:
04049 SearchLimit* const limit_1_;
04050 SearchLimit* const limit_2_;
04051 };
04052 }
04053
04054 SearchLimit* Solver::MakeLimit(SearchLimit* const limit_1,
04055 SearchLimit* const limit_2) {
04056 return RevAlloc(new ORLimit(limit_1, limit_2));
04057 }
04058
04059 void Solver::UpdateLimits(int64 time,
04060 int64 branches,
04061 int64 failures,
04062 int64 solutions,
04063 SearchLimit* limit) {
04064 reinterpret_cast<RegularLimit*>(limit)->UpdateLimits(time,
04065 branches,
04066 failures,
04067 solutions);
04068 }
04069
04070 int64 Solver::GetTime(SearchLimit* limit) {
04071 return reinterpret_cast<RegularLimit*>(limit)->wall_time();
04072 }
04073
04074 namespace {
04075 class CustomLimit : public SearchLimit {
04076 public:
04077 CustomLimit(Solver* const s, ResultCallback<bool>* limiter, bool del);
04078 virtual ~CustomLimit();
04079 virtual bool Check();
04080 virtual void Init();
04081 virtual void Copy(const SearchLimit* const limit);
04082 virtual SearchLimit* MakeClone() const;
04083
04084 private:
04085 ResultCallback<bool>* limiter_;
04086 bool delete_;
04087 };
04088
04089 CustomLimit::CustomLimit(Solver* const s,
04090 ResultCallback<bool>* limiter,
04091 bool del)
04092 : SearchLimit(s), limiter_(limiter), delete_(del) {
04093 limiter_->CheckIsRepeatable();
04094 }
04095
04096 CustomLimit::~CustomLimit() {
04097 if (delete_) {
04098 delete limiter_;
04099 }
04100 }
04101
04102 bool CustomLimit::Check() {
04103 return limiter_->Run();
04104 }
04105
04106 void CustomLimit::Init() {}
04107
04108 void CustomLimit::Copy(const SearchLimit* const limit) {
04109 const CustomLimit* const custom = reinterpret_cast<const CustomLimit* const>(limit);
04110 CHECK(!delete_) << "Cannot copy to non-cloned custom limit";
04111 limiter_ = custom->limiter_;
04112 }
04113
04114 SearchLimit* CustomLimit::MakeClone() const {
04115 Solver* const s = solver();
04116 return s->RevAlloc(new CustomLimit(s, limiter_, false));
04117 }
04118 }
04119
04120 SearchLimit* Solver::MakeCustomLimit(ResultCallback<bool>* limiter) {
04121 return RevAlloc(new CustomLimit(this, limiter, true));
04122 }
04123
04124
04125
04126 namespace {
04127 class SolveOnce : public DecisionBuilder {
04128 public:
04129 explicit SolveOnce(DecisionBuilder* const db) : db_(db) {
04130 CHECK(db != NULL);
04131 }
04132
04133 SolveOnce(DecisionBuilder* const db, const std::vector<SearchMonitor*>& monitors)
04134 : db_(db), monitors_(monitors) {
04135 CHECK(db != NULL);
04136 }
04137
04138 virtual ~SolveOnce() {}
04139
04140 virtual Decision* Next(Solver* s) {
04141 bool res = s->NestedSolve(db_, false, monitors_);
04142 if (!res) {
04143 s->Fail();
04144 }
04145 return NULL;
04146 }
04147
04148 virtual string DebugString() const {
04149 return StringPrintf("SolveOnce(%s)", db_->DebugString().c_str());
04150 }
04151
04152 virtual void Accept(ModelVisitor* const visitor) const {
04153 db_->Accept(visitor);
04154 }
04155
04156 private:
04157 DecisionBuilder* const db_;
04158 std::vector<SearchMonitor*> monitors_;
04159 };
04160 }
04161
04162 DecisionBuilder* Solver::MakeSolveOnce(DecisionBuilder* const db) {
04163 return RevAlloc(new SolveOnce(db));
04164 }
04165
04166 DecisionBuilder* Solver::MakeSolveOnce(DecisionBuilder* const db,
04167 SearchMonitor* const monitor1) {
04168 std::vector<SearchMonitor*> monitors;
04169 monitors.push_back(monitor1);
04170 return RevAlloc(new SolveOnce(db, monitors));
04171 }
04172
04173 DecisionBuilder* Solver::MakeSolveOnce(DecisionBuilder* const db,
04174 SearchMonitor* const monitor1,
04175 SearchMonitor* const monitor2) {
04176 std::vector<SearchMonitor*> monitors;
04177 monitors.push_back(monitor1);
04178 monitors.push_back(monitor2);
04179 return RevAlloc(new SolveOnce(db, monitors));
04180 }
04181
04182 DecisionBuilder* Solver::MakeSolveOnce(DecisionBuilder* const db,
04183 SearchMonitor* const monitor1,
04184 SearchMonitor* const monitor2,
04185 SearchMonitor* const monitor3) {
04186 std::vector<SearchMonitor*> monitors;
04187 monitors.push_back(monitor1);
04188 monitors.push_back(monitor2);
04189 monitors.push_back(monitor3);
04190 return RevAlloc(new SolveOnce(db, monitors));
04191 }
04192
04193 DecisionBuilder* Solver::MakeSolveOnce(DecisionBuilder* const db,
04194 SearchMonitor* const monitor1,
04195 SearchMonitor* const monitor2,
04196 SearchMonitor* const monitor3,
04197 SearchMonitor* const monitor4) {
04198 std::vector<SearchMonitor*> monitors;
04199 monitors.push_back(monitor1);
04200 monitors.push_back(monitor2);
04201 monitors.push_back(monitor3);
04202 monitors.push_back(monitor4);
04203 return RevAlloc(new SolveOnce(db, monitors));
04204 }
04205
04206 DecisionBuilder* Solver::MakeSolveOnce(DecisionBuilder* const db,
04207 const std::vector<SearchMonitor*>& monitors) {
04208 return RevAlloc(new SolveOnce(db, monitors));
04209 }
04210
04211
04212
04213 namespace {
04214 class NestedOptimize : public DecisionBuilder {
04215 public:
04216 NestedOptimize(DecisionBuilder* const db,
04217 Assignment* const solution,
04218 bool maximize,
04219 int64 step)
04220 : db_(db),
04221 solution_(solution),
04222 maximize_(maximize),
04223 step_(step),
04224 collector_(NULL) {
04225 CHECK_NOTNULL(db);
04226 CHECK_NOTNULL(solution);
04227 CHECK(solution->HasObjective());
04228 AddMonitors();
04229 }
04230
04231 NestedOptimize(DecisionBuilder* const db,
04232 Assignment* const solution,
04233 bool maximize,
04234 int64 step,
04235 const std::vector<SearchMonitor*>& monitors)
04236 : db_(db),
04237 solution_(solution),
04238 maximize_(maximize),
04239 step_(step),
04240 monitors_(monitors),
04241 collector_(NULL) {
04242 CHECK_NOTNULL(db);
04243 CHECK_NOTNULL(solution);
04244 CHECK(solution->HasObjective());
04245 AddMonitors();
04246 }
04247
04248 void AddMonitors() {
04249 Solver* const solver = solution_->solver();
04250 collector_ = solver->MakeLastSolutionCollector(solution_);
04251 monitors_.push_back(collector_);
04252 OptimizeVar* const optimize =
04253 solver->MakeOptimize(maximize_, solution_->Objective(), step_);
04254 monitors_.push_back(optimize);
04255 }
04256
04257 virtual Decision* Next(Solver* solver) {
04258 solver->NestedSolve(db_, true, monitors_);
04259 if (collector_->solution_count() == 0) {
04260 solver->Fail();
04261 }
04262 collector_->solution(0)->Restore();
04263 return NULL;
04264 }
04265
04266 virtual string DebugString() const {
04267 return StringPrintf("NestedOptimize(db = %s, maximize = %d, step = %lld)",
04268 db_->DebugString().c_str(),
04269 maximize_,
04270 step_);
04271 }
04272
04273 virtual void Accept(ModelVisitor* const visitor) const {
04274 db_->Accept(visitor);
04275 }
04276
04277 private:
04278 DecisionBuilder* const db_;
04279 Assignment* const solution_;
04280 const bool maximize_;
04281 const int64 step_;
04282 std::vector<SearchMonitor*> monitors_;
04283 SolutionCollector* collector_;
04284 };
04285 }
04286
04287 DecisionBuilder* Solver::MakeNestedOptimize(DecisionBuilder* const db,
04288 Assignment* const solution,
04289 bool maximize,
04290 int64 step) {
04291 return RevAlloc(new NestedOptimize(db, solution, maximize, step));
04292 }
04293
04294 DecisionBuilder* Solver::MakeNestedOptimize(DecisionBuilder* const db,
04295 Assignment* const solution,
04296 bool maximize,
04297 int64 step,
04298 SearchMonitor* const monitor1) {
04299 std::vector<SearchMonitor*> monitors;
04300 monitors.push_back(monitor1);
04301 return RevAlloc(new NestedOptimize(db, solution, maximize, step, monitors));
04302 }
04303
04304 DecisionBuilder* Solver::MakeNestedOptimize(DecisionBuilder* const db,
04305 Assignment* const solution,
04306 bool maximize,
04307 int64 step,
04308 SearchMonitor* const monitor1,
04309 SearchMonitor* const monitor2) {
04310 std::vector<SearchMonitor*> monitors;
04311 monitors.push_back(monitor1);
04312 monitors.push_back(monitor2);
04313 return RevAlloc(new NestedOptimize(db, solution, maximize, step, monitors));
04314 }
04315
04316 DecisionBuilder* Solver::MakeNestedOptimize(DecisionBuilder* const db,
04317 Assignment* const solution,
04318 bool maximize,
04319 int64 step,
04320 SearchMonitor* const monitor1,
04321 SearchMonitor* const monitor2,
04322 SearchMonitor* const monitor3) {
04323 std::vector<SearchMonitor*> monitors;
04324 monitors.push_back(monitor1);
04325 monitors.push_back(monitor2);
04326 monitors.push_back(monitor3);
04327 return RevAlloc(new NestedOptimize(db, solution, maximize, step, monitors));
04328 }
04329
04330 DecisionBuilder* Solver::MakeNestedOptimize(DecisionBuilder* const db,
04331 Assignment* const solution,
04332 bool maximize,
04333 int64 step,
04334 SearchMonitor* const monitor1,
04335 SearchMonitor* const monitor2,
04336 SearchMonitor* const monitor3,
04337 SearchMonitor* const monitor4) {
04338 std::vector<SearchMonitor*> monitors;
04339 monitors.push_back(monitor1);
04340 monitors.push_back(monitor2);
04341 monitors.push_back(monitor3);
04342 monitors.push_back(monitor4);
04343 return RevAlloc(new NestedOptimize(db, solution, maximize, step, monitors));
04344 }
04345
04346 DecisionBuilder* Solver::MakeNestedOptimize(
04347 DecisionBuilder* const db,
04348 Assignment* const solution,
04349 bool maximize,
04350 int64 step,
04351 const std::vector<SearchMonitor*>& monitors) {
04352 return RevAlloc(new NestedOptimize(db, solution, maximize, step, monitors));
04353 }
04354
04355
04356
04357
04358 namespace {
04359
04360 int64 NextLuby(int i) {
04361 DCHECK_GT(i, 0);
04362 DCHECK_LT(i, kint32max);
04363 int64 power;
04364
04365
04366 power = 2;
04367
04368 while (power < (i + 1)) {
04369 power <<= 1;
04370 }
04371 if (power == i + 1) {
04372 return (power / 2);
04373 }
04374 return NextLuby(i - (power / 2) + 1);
04375 }
04376
04377 class LubyRestart : public SearchMonitor {
04378 public:
04379 LubyRestart(Solver* const s, int scale_factor)
04380 : SearchMonitor(s),
04381 scale_factor_(scale_factor),
04382 iteration_(1),
04383 current_fails_(0),
04384 next_step_(scale_factor) {
04385 CHECK_GE(scale_factor, 1);
04386 }
04387 virtual ~LubyRestart() {}
04388
04389 virtual void BeginFail() {
04390 if (++current_fails_ >= next_step_) {
04391 current_fails_ = 0;
04392 next_step_ = NextLuby(++iteration_) * scale_factor_;
04393 RestartCurrentSearch();
04394 }
04395 }
04396
04397 virtual string DebugString() const {
04398 return StringPrintf("LubyRestart(%i)", scale_factor_);
04399 }
04400
04401 private:
04402 const int scale_factor_;
04403 int iteration_;
04404 int64 current_fails_;
04405 int64 next_step_;
04406 };
04407 }
04408
04409 SearchMonitor* Solver::MakeLubyRestart(int scale_factor) {
04410 return RevAlloc(new LubyRestart(this, scale_factor));
04411 }
04412
04413
04414
04415 namespace {
04416 class ConstantRestart : public SearchMonitor {
04417 public:
04418 ConstantRestart(Solver* const s, int frequency)
04419 : SearchMonitor(s),
04420 frequency_(frequency),
04421 current_fails_(0) {
04422 CHECK_GE(frequency, 1);
04423 }
04424 virtual ~ConstantRestart() {}
04425
04426 virtual void BeginFail() {
04427 if (++current_fails_ >= frequency_) {
04428 current_fails_ = 0;
04429 RestartCurrentSearch();
04430 }
04431 }
04432
04433 virtual string DebugString() const {
04434 return StringPrintf("ConstantRestart(%i)", frequency_);
04435 }
04436 private:
04437 const int frequency_;
04438 int64 current_fails_;
04439 };
04440 }
04441
04442 SearchMonitor* Solver::MakeConstantRestart(int frequency) {
04443 return RevAlloc(new ConstantRestart(this, frequency));
04444 }
04445
04446
04447
04448
04449
04450
04451
04452
04453
04454
04455
04456
04457
04458
04459
04460
04461
04462 class SymmetryManager : public SearchMonitor {
04463 public:
04464 SymmetryManager(Solver* const s,
04465 SymmetryBreaker* const * visitors,
04466 int size)
04467 : SearchMonitor(s),
04468 visitors_(new SymmetryBreaker*[size]),
04469 clauses_(new SimpleRevFIFO<IntVar*>[size]),
04470 decisions_(new SimpleRevFIFO<Decision*>[size]),
04471 directions_(new SimpleRevFIFO<bool>[size]),
04472 size_(size) {
04473 CHECK_GT(size, 0);
04474 memcpy(visitors_.get(), visitors, size_ * sizeof(*visitors));
04475 for (int i = 0; i < size_; ++i) {
04476 visitors_[i]->set_symmetry_manager_and_index(this, i);
04477 }
04478 }
04479
04480 virtual ~SymmetryManager() {}
04481
04482 virtual void EndNextDecision(DecisionBuilder* const db, Decision* const d) {
04483 if (d) {
04484 for (int i = 0; i < size_; ++i) {
04485 const void* const last = clauses_[i].Last();
04486 d->Accept(visitors_[i]);
04487 if (last != clauses_[i].Last()) {
04488
04489 decisions_[i].Push(solver(), d);
04490 directions_[i].Push(solver(), false);
04491 }
04492 }
04493 }
04494 }
04495
04496 virtual void RefuteDecision(Decision* d) {
04497 for (int i = 0; i < size_; ++i) {
04498 if (decisions_[i].Last() != NULL && decisions_[i].LastValue() == d) {
04499 CheckSymmetries(i);
04500 }
04501 }
04502 }
04503
04504
04505
04506 void CheckSymmetries(int index) {
04507 SimpleRevFIFO<IntVar*>::Iterator tmp(&clauses_[index]);
04508 SimpleRevFIFO<bool>::Iterator tmp_dir(&directions_[index]);
04509 Constraint* ct = NULL;
04510 {
04511 std::vector<IntVar*> guard;
04512
04513 ++tmp;
04514 ++tmp_dir;
04515 while (tmp.ok()) {
04516 IntVar* const term = *tmp;
04517 if (!*tmp_dir) {
04518 if (term->Max() == 0) {
04519
04520 return;
04521 }
04522 if (term->Min() == 0) {
04523 DCHECK_EQ(1, term->Max());
04524
04525 guard.push_back(term);
04526 }
04527 }
04528 ++tmp;
04529 ++tmp_dir;
04530 }
04531 guard.push_back(clauses_[index].LastValue());
04532 directions_[index].SetLastValue(true);
04533
04534
04535
04536
04537 ct = solver()->MakeEquality(solver()->MakeMin(guard), Zero());
04538 }
04539 DCHECK(ct != NULL);
04540 solver()->AddConstraint(ct);
04541 }
04542
04543 void AddTermToClause(SymmetryBreaker* const visitor, IntVar* const term) {
04544 clauses_[visitor->index_in_symmetry_manager()].Push(solver(), term);
04545 }
04546
04547 private:
04548 scoped_array<SymmetryBreaker*> visitors_;
04549 scoped_array<SimpleRevFIFO<IntVar*> > clauses_;
04550 scoped_array<SimpleRevFIFO<Decision*> > decisions_;
04551 scoped_array<SimpleRevFIFO<bool> > directions_;
04552 const int size_;
04553 };
04554
04555
04556
04557 void SymmetryBreaker::AddIntegerVariableEqualValueClause(IntVar* const var,
04558 int64 value) {
04559 CHECK_NOTNULL(var);
04560 Solver* const solver = var->solver();
04561 IntVar* const term = solver->MakeIsEqualCstVar(var, value);
04562 symmetry_manager()->AddTermToClause(this, term);
04563 }
04564
04565 void SymmetryBreaker::AddIntegerVariableGreaterOrEqualValueClause(
04566 IntVar* const var, int64 value) {
04567 CHECK_NOTNULL(var);
04568 Solver* const solver = var->solver();
04569 IntVar* const term = solver->MakeIsGreaterOrEqualCstVar(var, value);
04570 symmetry_manager()->AddTermToClause(this, term);
04571 }
04572
04573 void SymmetryBreaker::AddIntegerVariableLessOrEqualValueClause(
04574 IntVar* const var, int64 value) {
04575 CHECK_NOTNULL(var);
04576 Solver* const solver = var->solver();
04577 IntVar* const term = solver->MakeIsLessOrEqualCstVar(var, value);
04578 symmetry_manager()->AddTermToClause(this, term);
04579 }
04580
04581
04582
04583 SearchMonitor* Solver::MakeSymmetryManager(
04584 const std::vector<SymmetryBreaker*>& visitors) {
04585 return MakeSymmetryManager(visitors.data(), visitors.size());
04586 }
04587
04588 SearchMonitor* Solver::MakeSymmetryManager(SymmetryBreaker* const * visitors,
04589 int size) {
04590 return RevAlloc(new SymmetryManager(this, visitors, size));
04591 }
04592
04593 SearchMonitor* Solver::MakeSymmetryManager(SymmetryBreaker* const v1) {
04594 std::vector<SymmetryBreaker*> visitors;
04595 visitors.push_back(v1);
04596 return MakeSymmetryManager(visitors);
04597 }
04598
04599 SearchMonitor* Solver::MakeSymmetryManager(SymmetryBreaker* const v1,
04600 SymmetryBreaker* const v2) {
04601 std::vector<SymmetryBreaker*> visitors;
04602 visitors.push_back(v1);
04603 visitors.push_back(v2);
04604 return MakeSymmetryManager(visitors);
04605 }
04606
04607 SearchMonitor* Solver::MakeSymmetryManager(SymmetryBreaker* const v1,
04608 SymmetryBreaker* const v2,
04609 SymmetryBreaker* const v3) {
04610 std::vector<SymmetryBreaker*> visitors;
04611 visitors.push_back(v1);
04612 visitors.push_back(v2);
04613 visitors.push_back(v3);
04614 return MakeSymmetryManager(visitors);
04615 }
04616
04617 SearchMonitor* Solver::MakeSymmetryManager(SymmetryBreaker* const v1,
04618 SymmetryBreaker* const v2,
04619 SymmetryBreaker* const v3,
04620 SymmetryBreaker* const v4) {
04621 std::vector<SymmetryBreaker*> visitors;
04622 visitors.push_back(v1);
04623 visitors.push_back(v2);
04624 visitors.push_back(v3);
04625 visitors.push_back(v4);
04626 return MakeSymmetryManager(visitors);
04627 }
04628 }