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 "base/hash.h"
00018 #include <iterator>
00019 #include <set>
00020 #include <string>
00021 #include <utility>
00022 #include <vector>
00023
00024 #include "base/callback.h"
00025 #include "base/commandlineflags.h"
00026 #include "base/integral_types.h"
00027 #include "base/logging.h"
00028 #include "base/macros.h"
00029 #include "base/scoped_ptr.h"
00030 #include "base/bitmap.h"
00031 #include "base/concise_iterator.h"
00032 #include "base/map-util.h"
00033 #include "base/hash.h"
00034 #include "constraint_solver/constraint_solver.h"
00035 #include "constraint_solver/constraint_solveri.h"
00036 #include "graph/hamiltonian_path.h"
00037 #include "base/random.h"
00038
00039 DEFINE_int32(cp_local_search_sync_frequency, 16,
00040 "Frequency of checks for better solutions in the solution pool.");
00041
00042 DEFINE_int32(cp_local_search_tsp_opt_size, 13,
00043 "Size of TSPs solved in the TSPOpt operator.");
00044
00045 DEFINE_int32(cp_local_search_tsp_lns_size, 10,
00046 "Size of TSPs solved in the TSPLns operator.");
00047
00048 namespace operations_research {
00049
00050
00051
00052
00053
00054 bool LocalOptimumReached(Search* const search);
00055
00056
00057
00058 bool AcceptDelta(Search* const search,
00059 Assignment* delta,
00060 Assignment* deltadelta);
00061
00062
00063 void AcceptNeighbor(Search* const search);
00064
00065
00066
00067 IntVarLocalSearchOperator::IntVarLocalSearchOperator()
00068 : vars_(NULL),
00069 size_(0),
00070 values_(NULL),
00071 old_values_(NULL),
00072 activated_(0, false),
00073 was_activated_(0, false),
00074 has_changed_(0, false),
00075 has_delta_changed_(0, false),
00076 cleared_(true) {}
00077
00078 IntVarLocalSearchOperator::IntVarLocalSearchOperator(const IntVar* const* vars,
00079 int size)
00080 : vars_(NULL),
00081 size_(0),
00082 values_(NULL),
00083 old_values_(NULL),
00084 activated_(size, false),
00085 was_activated_(size, false),
00086 has_changed_(size, false),
00087 has_delta_changed_(size, false),
00088 cleared_(true) {
00089 CHECK_GE(size_, 0);
00090 AddVars(vars, size);
00091 }
00092
00093 IntVarLocalSearchOperator::~IntVarLocalSearchOperator() {}
00094
00095 void IntVarLocalSearchOperator::AddVars(const IntVar* const* vars, int size) {
00096 if (size > 0) {
00097 const int new_size = size_ + size;
00098 IntVar** new_vars = new IntVar*[new_size];
00099 if (size_ > 0) {
00100 memcpy(new_vars, vars_.get(), size_ * sizeof(*new_vars));
00101 }
00102 memcpy(new_vars + size_, vars, size * sizeof(*vars));
00103 vars_.reset(new_vars);
00104 values_.reset(new int64[new_size]);
00105 old_values_.reset(new int64[new_size]);
00106 activated_.Resize(new_size, false);
00107 was_activated_.Resize(new_size, false);
00108 has_changed_.Resize(new_size, false);
00109 has_delta_changed_.Resize(new_size, false);
00110 size_ = new_size;
00111 }
00112 }
00113
00114 void IntVarLocalSearchOperator::Start(const Assignment* assignment) {
00115 const Assignment::IntContainer& container = assignment->IntVarContainer();
00116 const int size = Size();
00117 CHECK_LE(size, container.Size())
00118 << "Assignment contains fewer variables than operator";
00119 for (int i = 0; i < size; ++i) {
00120 const IntVarElement* element = &(container.Element(i));
00121 IntVar* const var = vars_[i];
00122 if (element->Var() != var) {
00123 CHECK(container.Contains(var))
00124 << "Assignment does not contain operator variable " << var;
00125 element = &(container.Element(vars_[i]));
00126 }
00127 const int64 value = element->Value();
00128 values_[i] = value;
00129 old_values_[i] = value;
00130 const bool activated = element->Activated();
00131 activated_.Set(i, activated);
00132 was_activated_.Set(i, activated);
00133 }
00134 OnStart();
00135 }
00136
00137 void IntVarLocalSearchOperator::SetValue(int64 index, int64 value) {
00138 values_[index] = value;
00139 MarkChange(index);
00140 }
00141
00142 bool IntVarLocalSearchOperator::Activated(int64 index) const {
00143 return activated_.Get(index);
00144 }
00145
00146 void IntVarLocalSearchOperator::Activate(int64 index) {
00147 activated_.Set(index, true);
00148 MarkChange(index);
00149 }
00150
00151 void IntVarLocalSearchOperator::Deactivate(int64 index) {
00152 activated_.Set(index, false);
00153 MarkChange(index);
00154 }
00155
00156 bool IntVarLocalSearchOperator::ApplyChanges(Assignment* delta,
00157 Assignment* deltadelta) const {
00158 for (ConstIter<std::vector<int64> > it(changes_); !it.at_end(); ++it) {
00159 const int64 index = *it;
00160 IntVar* var = Var(index);
00161 const int64 value = Value(index);
00162 const bool activated = activated_.Get(index);
00163 if (!activated) {
00164 if (!cleared_ && has_delta_changed_.Get(index) && IsIncremental()) {
00165 deltadelta->FastAdd(var).Deactivate();
00166 }
00167 delta->FastAdd(var).Deactivate();
00168 } else if (value != OldValue(index) || !SkipUnchanged(index)) {
00169 if (!cleared_ && has_delta_changed_.Get(index) && IsIncremental()) {
00170 deltadelta->FastAdd(var).SetValue(value);
00171 }
00172 delta->FastAdd(var).SetValue(value);
00173 }
00174 }
00175 return true;
00176 }
00177
00178 void IntVarLocalSearchOperator::RevertChanges(bool incremental) {
00179 cleared_ = false;
00180 has_delta_changed_.SetAll(false);
00181 if (incremental && IsIncremental()) return;
00182 cleared_ = true;
00183 for (ConstIter<std::vector<int64> > it(changes_); !it.at_end(); ++it) {
00184 const int index = *it;
00185 values_[index] = old_values_[index];
00186 activated_.Set(index, was_activated_.Get(index));
00187 has_changed_.Set(index, false);
00188 }
00189 changes_.clear();
00190 }
00191
00192 void IntVarLocalSearchOperator::MarkChange(int64 index) {
00193 if (!has_delta_changed_.Get(index)) {
00194 has_delta_changed_.Set(index, true);
00195 }
00196 if (!has_changed_.Get(index)) {
00197 changes_.push_back(index);
00198 has_changed_.Set(index, true);
00199 }
00200 }
00201
00202 bool IntVarLocalSearchOperator::MakeNextNeighbor(Assignment* delta,
00203 Assignment* deltadelta) {
00204 CHECK_NOTNULL(delta);
00205 while (true) {
00206 RevertChanges(true);
00207
00208 if (!MakeOneNeighbor()) {
00209 return false;
00210 }
00211
00212 if (ApplyChanges(delta, deltadelta)) {
00213 VLOG(2) << "Delta = " << delta->DebugString();
00214 return true;
00215 }
00216 }
00217 return false;
00218 }
00219
00220 bool IntVarLocalSearchOperator::MakeOneNeighbor() {
00221 return true;
00222 }
00223
00224
00225
00226 SequenceVarLocalSearchOperator::SequenceVarLocalSearchOperator()
00227 : vars_(NULL),
00228 size_(0),
00229 values_(NULL),
00230 backward_values_(NULL),
00231 old_values_(NULL),
00232 activated_(0, false),
00233 was_activated_(0, false),
00234 has_changed_(0, false),
00235 has_delta_changed_(0, false),
00236 cleared_(true) {}
00237
00238 SequenceVarLocalSearchOperator::SequenceVarLocalSearchOperator(
00239 const SequenceVar* const* vars, int size)
00240 : vars_(NULL),
00241 size_(0),
00242 values_(NULL),
00243 backward_values_(NULL),
00244 old_values_(NULL),
00245 activated_(size, false),
00246 was_activated_(size, false),
00247 has_changed_(size, false),
00248 has_delta_changed_(size, false),
00249 cleared_(true) {
00250 CHECK_GE(size_, 0);
00251 AddVars(vars, size);
00252 }
00253
00254 SequenceVarLocalSearchOperator::~SequenceVarLocalSearchOperator() {}
00255
00256 void SequenceVarLocalSearchOperator::AddVars(const SequenceVar* const* vars,
00257 int size) {
00258 if (size > 0) {
00259 const int new_size = size_ + size;
00260 SequenceVar** const new_vars = new SequenceVar*[new_size];
00261 if (size_ > 0) {
00262 memcpy(new_vars, vars_.get(), size_ * sizeof(*new_vars));
00263 }
00264 memcpy(new_vars + size_, vars, size * sizeof(*vars));
00265 vars_.reset(new_vars);
00266 values_.reset(new std::vector<int>[new_size]);
00267 backward_values_.reset(new std::vector<int>[new_size]);
00268 old_values_.reset(new std::vector<int>[new_size]);
00269 activated_.Resize(new_size, false);
00270 was_activated_.Resize(new_size, false);
00271 has_changed_.Resize(new_size, false);
00272 has_delta_changed_.Resize(new_size, false);
00273 size_ = new_size;
00274 }
00275 }
00276
00277 void SequenceVarLocalSearchOperator::Start(const Assignment* assignment) {
00278 const Assignment::SequenceContainer& container =
00279 assignment->SequenceVarContainer();
00280 const int size = Size();
00281 CHECK_LE(size, container.Size())
00282 << "Assignment contains fewer variables than operator";
00283 for (int i = 0; i < size; ++i) {
00284 const SequenceVarElement* element = &(container.Element(i));
00285 SequenceVar* const var = vars_[i];
00286 if (element->Var() != var) {
00287 CHECK(container.Contains(var))
00288 << "Assignment does not contain operator variable " << var;
00289 element = &(container.Element(vars_[i]));
00290 }
00291 const std::vector<int>& value = element->ForwardSequence();
00292 CHECK_EQ(vars_[i]->size(), value.size());
00293 values_[i] = value;
00294 backward_values_[i].clear();
00295 old_values_[i] = value;
00296 const bool activated = element->Activated();
00297 activated_.Set(i, activated);
00298 was_activated_.Set(i, activated);
00299 }
00300 OnStart();
00301 }
00302
00303 void SequenceVarLocalSearchOperator::SetForwardSequence(
00304 int64 index, const std::vector<int>& value) {
00305 values_[index] = value;
00306 MarkChange(index);
00307 }
00308
00309 void SequenceVarLocalSearchOperator::SetBackwardSequence(
00310 int64 index, const std::vector<int>& value) {
00311 backward_values_[index] = value;
00312 MarkChange(index);
00313 }
00314
00315 bool SequenceVarLocalSearchOperator::Activated(int64 index) const {
00316 return activated_.Get(index);
00317 }
00318
00319 void SequenceVarLocalSearchOperator::Activate(int64 index) {
00320 activated_.Set(index, true);
00321 MarkChange(index);
00322 }
00323
00324 void SequenceVarLocalSearchOperator::Deactivate(int64 index) {
00325 activated_.Set(index, false);
00326 MarkChange(index);
00327 }
00328
00329 bool SequenceVarLocalSearchOperator::ApplyChanges(
00330 Assignment* delta,
00331 Assignment* deltadelta) const {
00332 for (ConstIter<std::vector<int64> > it(changes_); !it.at_end(); ++it) {
00333 const int64 index = *it;
00334 SequenceVar* const var = Var(index);
00335 const std::vector<int>& value = Sequence(index);
00336 const bool activated = activated_.Get(index);
00337 if (!activated) {
00338 if (!cleared_ && has_delta_changed_.Get(index) && IsIncremental()) {
00339 deltadelta->FastAdd(var).Deactivate();
00340 }
00341 delta->FastAdd(var).Deactivate();
00342 } else if (value != OldSequence(index) || !SkipUnchanged(index)) {
00343 if (!cleared_ && has_delta_changed_.Get(index) && IsIncremental()) {
00344 SequenceVarElement* const fast_element = &deltadelta->FastAdd(var);
00345 fast_element->SetForwardSequence(value);
00346 fast_element->SetBackwardSequence(backward_values_[index]);
00347 }
00348 SequenceVarElement* const element = &delta->FastAdd(var);
00349 element->SetForwardSequence(value);
00350 element->SetBackwardSequence(backward_values_[index]);
00351 }
00352 }
00353 return true;
00354 }
00355
00356 void SequenceVarLocalSearchOperator::RevertChanges(bool incremental) {
00357 cleared_ = false;
00358 has_delta_changed_.SetAll(false);
00359 if (incremental && IsIncremental()) return;
00360 cleared_ = true;
00361 for (ConstIter<std::vector<int64> > it(changes_); !it.at_end(); ++it) {
00362 const int index = *it;
00363 values_[index] = old_values_[index];
00364 backward_values_[index].clear();
00365 activated_.Set(index, was_activated_.Get(index));
00366 has_changed_.Set(index, false);
00367 }
00368 changes_.clear();
00369 }
00370
00371 void SequenceVarLocalSearchOperator::MarkChange(int64 index) {
00372 if (!has_delta_changed_.Get(index)) {
00373 has_delta_changed_.Set(index, true);
00374 }
00375 if (!has_changed_.Get(index)) {
00376 changes_.push_back(index);
00377 has_changed_.Set(index, true);
00378 }
00379 }
00380
00381
00382
00383 BaseLNS::BaseLNS(const IntVar* const* vars, int size)
00384 : IntVarLocalSearchOperator(vars, size) {}
00385
00386 BaseLNS::~BaseLNS() {}
00387
00388 bool BaseLNS::MakeOneNeighbor() {
00389 std::vector<int> fragment;
00390 if (NextFragment(&fragment)) {
00391 for (int i = 0; i < fragment.size(); ++i) {
00392 DCHECK_LT(fragment[i], Size());
00393 Deactivate(fragment[i]);
00394 }
00395 return true;
00396 } else {
00397 return false;
00398 }
00399 }
00400
00401 void BaseLNS::OnStart() {
00402 InitFragments();
00403 }
00404
00405 void BaseLNS::InitFragments() {}
00406
00407
00408
00409
00410
00411 namespace {
00412 class SimpleLNS : public BaseLNS {
00413 public:
00414 SimpleLNS(const IntVar* const* vars, int size, int number_of_variables)
00415 : BaseLNS(vars, size),
00416 index_(0),
00417 number_of_variables_(number_of_variables) {
00418 CHECK_GT(number_of_variables_, 0);
00419 }
00420 ~SimpleLNS() {}
00421 virtual void InitFragments() { index_ = 0; }
00422 virtual bool NextFragment(std::vector<int>* fragment);
00423 private:
00424 int index_;
00425 const int number_of_variables_;
00426 };
00427
00428 bool SimpleLNS::NextFragment(std::vector<int>* fragment) {
00429 const int size = Size();
00430 if (index_ < size) {
00431 for (int i = index_; i < index_ + number_of_variables_; ++i) {
00432 fragment->push_back(i % size);
00433 }
00434 ++index_;
00435 return true;
00436 } else {
00437 return false;
00438 }
00439 }
00440
00441
00442
00443
00444
00445 class RandomLNS : public BaseLNS {
00446 public:
00447 RandomLNS(const IntVar* const* vars,
00448 int size,
00449 int number_of_variables,
00450 int32 seed)
00451 : BaseLNS(vars, size),
00452 rand_(seed),
00453 number_of_variables_(number_of_variables) {
00454 CHECK_GT(number_of_variables_, 0);
00455 CHECK_LE(number_of_variables_, Size());
00456 }
00457 ~RandomLNS() {}
00458 virtual bool NextFragment(std::vector<int>* fragment);
00459 private:
00460 ACMRandom rand_;
00461 const int number_of_variables_;
00462 };
00463
00464 bool RandomLNS::NextFragment(std::vector<int>* fragment) {
00465 for (int i = 0; i < number_of_variables_; ++i) {
00466 fragment->push_back(rand_.Uniform(Size()));
00467 }
00468 return true;
00469 }
00470 }
00471
00472 LocalSearchOperator* Solver::MakeRandomLNSOperator(const std::vector<IntVar*>& vars,
00473 int number_of_variables) {
00474 return MakeRandomLNSOperator(vars.data(), vars.size(), number_of_variables);
00475 }
00476
00477 LocalSearchOperator* Solver::MakeRandomLNSOperator(const std::vector<IntVar*>& vars,
00478 int number_of_variables,
00479 int32 seed) {
00480 return MakeRandomLNSOperator(vars.data(),
00481 vars.size(),
00482 number_of_variables,
00483 seed);
00484 }
00485
00486 LocalSearchOperator* Solver::MakeRandomLNSOperator(const IntVar* const* vars,
00487 int size,
00488 int number_of_variables) {
00489 return MakeRandomLNSOperator(vars,
00490 size,
00491 number_of_variables,
00492 ACMRandom::HostnamePidTimeSeed());
00493 }
00494
00495 LocalSearchOperator* Solver::MakeRandomLNSOperator(const IntVar* const* vars,
00496 int size,
00497 int number_of_variables,
00498 int32 seed) {
00499 return RevAlloc(new RandomLNS(vars, size, number_of_variables, seed));
00500 }
00501
00502
00503
00504
00505
00506
00507 namespace {
00508 class MoveTowardTargetLS: public IntVarLocalSearchOperator {
00509 public:
00510 MoveTowardTargetLS(const std::vector<IntVar*>& variables,
00511 const std::vector<int64>& target_values)
00512 : IntVarLocalSearchOperator(variables.data(), variables.size()),
00513 target_(target_values),
00514
00515
00516
00517 variable_index_(Size() - 1) {
00518 CHECK_EQ(target_values.size(), variables.size()) << "Illegal arguments.";
00519 }
00520
00521 virtual ~MoveTowardTargetLS() {}
00522
00523 protected:
00524
00525 virtual bool MakeOneNeighbor() {
00526 while (num_var_since_last_start_ < Size()) {
00527 ++num_var_since_last_start_;
00528 variable_index_ = (variable_index_ + 1) % Size();
00529 const int64 target_value = target_.at(variable_index_);
00530 const int64 current_value = OldValue(variable_index_);
00531 if (current_value != target_value) {
00532 SetValue(variable_index_, target_value);
00533 return true;
00534 }
00535 }
00536 return false;
00537 }
00538
00539 private:
00540 virtual void OnStart() {
00541
00542
00543
00544
00545
00546
00547
00548
00549
00550
00551
00552 CHECK_GE(variable_index_, 0);
00553 CHECK_LT(variable_index_, Size());
00554 num_var_since_last_start_ = 0;
00555 }
00556
00557
00558 const std::vector<int64> target_;
00559
00560
00561 int64 variable_index_;
00562
00563
00564 int64 num_var_since_last_start_;
00565 };
00566 }
00567
00568 LocalSearchOperator* Solver::MakeMoveTowardTargetOperator(
00569 const Assignment& target) {
00570 typedef std::vector<IntVarElement> Elements;
00571 const Elements& elements = target.IntVarContainer().elements();
00572
00573 std::vector<IntVar*> vars;
00574 std::vector<int64> values;
00575 vars.reserve(target.NumIntVars());
00576 values.reserve(target.NumIntVars());
00577 for (ConstIter<Elements> it(elements); !it.at_end(); ++it) {
00578 vars.push_back(it->Var());
00579 values.push_back(it->Value());
00580 }
00581 return MakeMoveTowardTargetOperator(vars, values);
00582 }
00583
00584 LocalSearchOperator* Solver::MakeMoveTowardTargetOperator(
00585 const std::vector<IntVar*>& variables,
00586 const std::vector<int64>& target_values) {
00587 return RevAlloc(new MoveTowardTargetLS(variables, target_values));
00588 }
00589
00590
00591
00592 ChangeValue::ChangeValue(const IntVar* const* vars, int size)
00593 : IntVarLocalSearchOperator(vars, size), index_(0) {}
00594
00595 ChangeValue::~ChangeValue() {}
00596
00597 bool ChangeValue::MakeOneNeighbor() {
00598 const int size = Size();
00599 while (index_ < size) {
00600 const int64 value = ModifyValue(index_, Value(index_));
00601 SetValue(index_, value);
00602 ++index_;
00603 return true;
00604 }
00605 return false;
00606 }
00607
00608 void ChangeValue::OnStart() {
00609 index_ = 0;
00610 }
00611
00612
00613
00614 namespace {
00615 class IncrementValue : public ChangeValue {
00616 public:
00617 IncrementValue(const IntVar* const* vars, int size)
00618 : ChangeValue(vars, size) {}
00619 virtual ~IncrementValue() {}
00620 virtual int64 ModifyValue(int64 index, int64 value) { return value + 1; }
00621 };
00622
00623
00624
00625 class DecrementValue : public ChangeValue {
00626 public:
00627 DecrementValue(const IntVar* const* vars, int size)
00628 : ChangeValue(vars, size) {}
00629 virtual ~DecrementValue() {}
00630 virtual int64 ModifyValue(int64 index, int64 value) { return value - 1; }
00631 };
00632 }
00633
00634
00635
00636 PathOperator::PathOperator(const IntVar* const* next_vars,
00637 const IntVar* const* path_vars,
00638 int size,
00639 int number_of_base_nodes)
00640 : IntVarLocalSearchOperator(next_vars, size),
00641 number_of_nexts_(size),
00642 ignore_path_vars_(path_vars == NULL),
00643 base_nodes_(number_of_base_nodes),
00644 end_nodes_(number_of_base_nodes),
00645 base_paths_(number_of_base_nodes),
00646 just_started_(false),
00647 first_start_(true) {
00648 if (!ignore_path_vars_) {
00649 AddVars(path_vars, size);
00650 }
00651 }
00652
00653 void PathOperator::OnStart() {
00654 InitializeBaseNodes();
00655 OnNodeInitialization();
00656 }
00657
00658 bool PathOperator::MakeOneNeighbor() {
00659 while (IncrementPosition()) {
00660
00661
00662 RevertChanges(true);
00663 if (MakeNeighbor()) {
00664 return true;
00665 }
00666 }
00667 return false;
00668 }
00669
00670 bool PathOperator::SkipUnchanged(int index) const {
00671 if (ignore_path_vars_) {
00672 return true;
00673 }
00674 if (index < number_of_nexts_) {
00675 int path_index = index + number_of_nexts_;
00676 return Value(path_index) == OldValue(path_index);
00677 } else {
00678 int next_index = index - number_of_nexts_;
00679 return Value(next_index) == OldValue(next_index);
00680 }
00681 }
00682
00683 bool PathOperator::MoveChain(int64 before_chain,
00684 int64 chain_end,
00685 int64 destination) {
00686 if (CheckChainValidity(before_chain, chain_end, destination)
00687 && !IsPathEnd(chain_end)
00688 && !IsPathEnd(destination)) {
00689 const int64 destination_path = Path(destination);
00690 const int64 after_chain = Next(chain_end);
00691 SetNext(chain_end, Next(destination), destination_path);
00692 if (!ignore_path_vars_) {
00693 int current = destination;
00694 int next = Next(before_chain);
00695 while (current != chain_end) {
00696 SetNext(current, next, destination_path);
00697 current = next;
00698 next = Next(next);
00699 }
00700 } else {
00701 SetNext(destination, Next(before_chain), destination_path);
00702 }
00703 SetNext(before_chain, after_chain, Path(before_chain));
00704 return true;
00705 }
00706 return false;
00707 }
00708
00709 bool PathOperator::ReverseChain(int64 before_chain,
00710 int64 after_chain,
00711 int64* chain_last) {
00712 if (CheckChainValidity(before_chain, after_chain, -1)) {
00713 int64 path = Path(before_chain);
00714 int64 current = Next(before_chain);
00715 if (current == after_chain) {
00716 return false;
00717 }
00718 int64 current_next = Next(current);
00719 SetNext(current, after_chain, path);
00720 while (current_next != after_chain) {
00721 const int64 next = Next(current_next);
00722 SetNext(current_next, current, path);
00723 current = current_next;
00724 current_next = next;
00725 }
00726 SetNext(before_chain, current, path);
00727 *chain_last = current;
00728 return true;
00729 }
00730 return false;
00731 }
00732
00733 bool PathOperator::MakeActive(int64 node, int64 destination) {
00734 if (!IsPathEnd(destination)) {
00735 int64 destination_path = Path(destination);
00736 SetNext(node, Next(destination), destination_path);
00737 SetNext(destination, node, destination_path);
00738 return true;
00739 } else {
00740 return false;
00741 }
00742 }
00743
00744 bool PathOperator::MakeChainInactive(int64 before_chain, int64 chain_end) {
00745 const int64 kNoPath = -1;
00746 if (CheckChainValidity(before_chain, chain_end, -1)
00747 && !IsPathEnd(chain_end)) {
00748 const int64 after_chain = Next(chain_end);
00749 int64 current = Next(before_chain);
00750 while (current != after_chain) {
00751 const int64 next = Next(current);
00752 SetNext(current, current, kNoPath);
00753 current = next;
00754 }
00755 SetNext(before_chain, after_chain, Path(before_chain));
00756 return true;
00757 }
00758 return false;
00759 }
00760
00761 bool PathOperator::CheckEnds() const {
00762 const int base_node_size = base_nodes_.size();
00763 for (int i = 0; i < base_node_size; ++i) {
00764 if (base_nodes_[i] != end_nodes_[i]) {
00765 return true;
00766 }
00767 }
00768 return false;
00769 }
00770
00771 bool PathOperator::IncrementPosition() {
00772 const int base_node_size = base_nodes_.size();
00773 if (!just_started_) {
00774 const int number_of_paths = path_starts_.size();
00775
00776
00777
00778
00779
00780 int last_restarted = base_node_size;
00781 for (int i = base_node_size - 1; i >= 0; --i) {
00782 if (base_nodes_[i] < number_of_nexts_) {
00783 base_nodes_[i] = OldNext(base_nodes_[i]);
00784 break;
00785 }
00786 base_nodes_[i] = StartNode(i);
00787 last_restarted = i;
00788 }
00789
00790
00791
00792
00793
00794
00795
00796
00797
00798 for (int i = last_restarted; i < base_node_size; ++i) {
00799 base_nodes_[i] = GetBaseNodeRestartPosition(i);
00800 }
00801 if (last_restarted > 0) {
00802 return CheckEnds();
00803 }
00804
00805 for (int i = base_node_size - 1; i >= 0; --i) {
00806 const int next_path_index = base_paths_[i] + 1;
00807 if (next_path_index < number_of_paths) {
00808 base_paths_[i] = next_path_index;
00809 base_nodes_[i] = path_starts_[next_path_index];
00810 if (i == 0 || !OnSamePathAsPreviousBase(i)) {
00811 return CheckEnds();
00812 }
00813 } else {
00814 base_paths_[i] = 0;
00815 base_nodes_[i] = path_starts_[0];
00816 }
00817 }
00818 } else {
00819 just_started_ = false;
00820 return true;
00821 }
00822 return CheckEnds();
00823 }
00824
00825 void PathOperator::InitializePathStarts() {
00826 path_starts_.clear();
00827 Bitmap has_prevs(number_of_nexts_, false);
00828 for (int i = 0; i < number_of_nexts_; ++i) {
00829 const int next = OldNext(i);
00830 if (next < number_of_nexts_) {
00831 has_prevs.Set(next, true);
00832 }
00833 }
00834 for (int i = 0; i < number_of_nexts_; ++i) {
00835 if (!has_prevs.Get(i)) {
00836 path_starts_.push_back(i);
00837 }
00838 }
00839 }
00840
00841 void PathOperator::InitializeInactives() {
00842 inactives_.clear();
00843 for (int i = 0; i < number_of_nexts_; ++i) {
00844 inactives_.push_back(OldNext(i) == i);
00845 }
00846 }
00847
00848 void PathOperator::InitializeBaseNodes() {
00849 InitializePathStarts();
00850 InitializeInactives();
00851 if (first_start_ || InitPosition()) {
00852
00853
00854 for (int i = 0; i < base_nodes_.size(); ++i) {
00855 base_paths_[i] = 0;
00856 base_nodes_[i] = path_starts_[0];
00857 }
00858 first_start_ = false;
00859 }
00860 for (int i = 0; i < base_nodes_.size(); ++i) {
00861
00862 int64 base_node = base_nodes_[i];
00863 if (RestartAtPathStartOnSynchronize() || IsInactive(base_node)) {
00864 base_node = path_starts_[base_paths_[i]];
00865 base_nodes_[i] = base_node;
00866 }
00867 end_nodes_[i] = base_node;
00868 }
00869
00870
00871 for (int i = 1; i < base_nodes_.size(); ++i) {
00872 if (OnSamePathAsPreviousBase(i)
00873 && !OnSamePath(base_nodes_[i - 1], base_nodes_[i])) {
00874 const int64 base_node = base_nodes_[i -1];
00875 base_nodes_[i] = base_node;
00876 end_nodes_[i] = base_node;
00877 }
00878 }
00879 just_started_ = true;
00880 }
00881
00882 bool PathOperator::OnSamePath(int64 node1, int64 node2) const {
00883 if (IsInactive(node1) != IsInactive(node2)) {
00884 return false;
00885 }
00886 for (int node = node1; !IsPathEnd(node); node = OldNext(node)) {
00887 if (node == node2) {
00888 return true;
00889 }
00890 }
00891 for (int node = node2; !IsPathEnd(node); node = OldNext(node)) {
00892 if (node == node1) {
00893 return true;
00894 }
00895 }
00896 return false;
00897 }
00898
00899
00900
00901
00902
00903
00904 bool PathOperator::CheckChainValidity(int64 before_chain,
00905 int64 chain_end,
00906 int64 exclude) const {
00907 if (before_chain == chain_end || before_chain == exclude) return false;
00908 int64 current = before_chain;
00909 int chain_size = 0;
00910 while (current != chain_end) {
00911 if (chain_size > number_of_nexts_) {
00912 return false;
00913 }
00914 if (IsPathEnd(current)) {
00915 return false;
00916 }
00917 current = Next(current);
00918 ++chain_size;
00919 if (current == exclude) {
00920 return false;
00921 }
00922 }
00923 return true;
00924 }
00925
00926 namespace {
00927
00928
00929
00930
00931
00932
00933
00934
00935
00936
00937 class TwoOpt : public PathOperator {
00938 public:
00939 TwoOpt(const IntVar* const* vars,
00940 const IntVar* const* secondary_vars,
00941 int size)
00942 : PathOperator(vars, secondary_vars, size, 2), last_base_(-1), last_(-1) {
00943 }
00944 virtual ~TwoOpt() {}
00945 virtual bool MakeNeighbor();
00946 virtual bool IsIncremental() const { return true; }
00947
00948 protected:
00949 virtual bool OnSamePathAsPreviousBase(int64 base_index) {
00950
00951 return true;
00952 }
00953
00954 private:
00955 virtual void OnNodeInitialization() { last_ = -1; }
00956
00957 int64 last_base_;
00958 int64 last_;
00959 };
00960
00961 bool TwoOpt::MakeNeighbor() {
00962 DCHECK_EQ(StartNode(0), StartNode(1));
00963 if (last_base_ != BaseNode(0) || last_ == -1) {
00964 RevertChanges(false);
00965 if (IsPathEnd(BaseNode(0))) {
00966 last_ = -1;
00967 return false;
00968 }
00969 last_base_ = BaseNode(0);
00970 last_ = Next(BaseNode(0));
00971 int64 chain_last;
00972 if (ReverseChain(BaseNode(0), BaseNode(1), &chain_last)) {
00973 return true;
00974 } else {
00975 last_ = -1;
00976 return false;
00977 }
00978 } else {
00979 const int64 to_move = Next(last_);
00980 DCHECK_EQ(Next(to_move), BaseNode(1));
00981 return MoveChain(last_, to_move, BaseNode(0));
00982 }
00983 }
00984
00985
00986
00987
00988
00989
00990
00991
00992
00993
00994
00995
00996
00997
00998
00999
01000 class Relocate : public PathOperator {
01001 public:
01002 Relocate(const IntVar* const* vars,
01003 const IntVar* const* secondary_vars,
01004 int size,
01005 int64 chain_length = 1LL,
01006 bool single_path = false)
01007 : PathOperator(vars, secondary_vars, size, 2),
01008 chain_length_(chain_length),
01009 single_path_(single_path) {
01010 CHECK_GT(chain_length_, 0);
01011 }
01012 virtual ~Relocate() {}
01013 virtual bool MakeNeighbor();
01014
01015 protected:
01016 virtual bool OnSamePathAsPreviousBase(int64 base_index) {
01017
01018
01019 return single_path_;
01020 }
01021
01022 private:
01023 const int64 chain_length_;
01024 const bool single_path_;
01025 };
01026
01027 bool Relocate::MakeNeighbor() {
01028 DCHECK(!single_path_ || StartNode(0) == StartNode(1));
01029 const int64 before_chain = BaseNode(0);
01030 int64 chain_end = before_chain;
01031 for (int i = 0; i < chain_length_; ++i) {
01032 if (IsPathEnd(chain_end)) {
01033 return false;
01034 }
01035 chain_end = Next(chain_end);
01036 }
01037 const int64 destination = BaseNode(1);
01038 return MoveChain(before_chain, chain_end, destination);
01039 }
01040
01041
01042
01043
01044
01045
01046
01047
01048
01049
01050
01051 class Exchange : public PathOperator {
01052 public:
01053 Exchange(const IntVar* const* vars,
01054 const IntVar* const* secondary_vars,
01055 int size)
01056 : PathOperator(vars, secondary_vars, size, 2) {}
01057 virtual ~Exchange() {}
01058 virtual bool MakeNeighbor();
01059 };
01060
01061 bool Exchange::MakeNeighbor() {
01062 const int64 prev_node0 = BaseNode(0);
01063 if (IsPathEnd(prev_node0)) return false;
01064 const int64 node0 = Next(prev_node0);
01065 const int64 prev_node1 = BaseNode(1);
01066 if (IsPathEnd(prev_node1)) return false;
01067 const int64 node1 = Next(prev_node1);
01068 if (node0 == prev_node1) {
01069 return MoveChain(prev_node1, node1, prev_node0);
01070 } else if (node1 == prev_node0) {
01071 return MoveChain(prev_node0, node0, prev_node1);
01072 } else {
01073 return MoveChain(prev_node0, node0, prev_node1)
01074 && MoveChain(node0, Next(node0), prev_node0);
01075 }
01076 return false;
01077 }
01078
01079
01080
01081
01082
01083
01084
01085
01086
01087
01088
01089
01090
01091 class Cross : public PathOperator {
01092 public:
01093 Cross(const IntVar* const* vars,
01094 const IntVar* const* secondary_vars,
01095 int size)
01096 : PathOperator(vars, secondary_vars, size, 2) {}
01097 virtual ~Cross() {}
01098 virtual bool MakeNeighbor();
01099 };
01100
01101 bool Cross::MakeNeighbor() {
01102 const int64 node0 = BaseNode(0);
01103 const int64 start0 = StartNode(0);
01104 const int64 node1 = BaseNode(1);
01105 const int64 start1 = StartNode(1);
01106 if (start1 == start0) {
01107 return false;
01108 }
01109 if (!IsPathEnd(node0) && !IsPathEnd(node1)) {
01110 return MoveChain(start0, node0, start1)
01111 && MoveChain(node0, node1, start0);
01112 } else if (!IsPathEnd(node0)) {
01113 return MoveChain(start0, node0, start1);
01114 } else if (!IsPathEnd(node1)) {
01115 return MoveChain(start1, node1, start0);
01116 }
01117 return false;
01118 }
01119
01120
01121
01122
01123 class BaseInactiveNodeToPathOperator : public PathOperator {
01124 public:
01125 BaseInactiveNodeToPathOperator(const IntVar* const* vars,
01126 const IntVar* const* secondary_vars,
01127 int size,
01128 int number_of_base_nodes)
01129 : PathOperator(vars, secondary_vars, size, number_of_base_nodes),
01130 inactive_node_(0) {}
01131 virtual ~BaseInactiveNodeToPathOperator() {}
01132
01133 protected:
01134 virtual bool MakeOneNeighbor();
01135 int64 GetInactiveNode() const { return inactive_node_; }
01136
01137 private:
01138 virtual void OnNodeInitialization();
01139
01140 int inactive_node_;
01141 };
01142
01143 void BaseInactiveNodeToPathOperator::OnNodeInitialization() {
01144 for (int i = 0; i < Size(); ++i) {
01145 if (IsInactive(i)) {
01146 inactive_node_ = i;
01147 return;
01148 }
01149 }
01150 inactive_node_ = Size();
01151 }
01152
01153 bool BaseInactiveNodeToPathOperator::MakeOneNeighbor() {
01154 while (inactive_node_ < Size()) {
01155 if (!IsInactive(inactive_node_) || !PathOperator::MakeOneNeighbor()) {
01156 ResetPosition();
01157 ++inactive_node_;
01158 } else {
01159 return true;
01160 }
01161 }
01162 return false;
01163 }
01164
01165
01166
01167
01168
01169
01170
01171
01172
01173
01174 class MakeActiveOperator : public BaseInactiveNodeToPathOperator {
01175 public:
01176 MakeActiveOperator(const IntVar* const* vars,
01177 const IntVar* const* secondary_vars,
01178 int size)
01179 : BaseInactiveNodeToPathOperator(vars, secondary_vars, size, 1) {}
01180 virtual ~MakeActiveOperator() {}
01181 virtual bool MakeNeighbor();
01182 };
01183
01184 bool MakeActiveOperator::MakeNeighbor() {
01185 return MakeActive(GetInactiveNode(), BaseNode(0));
01186 }
01187
01188
01189
01190
01191
01192
01193
01194
01195
01196 class MakeInactiveOperator : public PathOperator {
01197 public:
01198 MakeInactiveOperator(const IntVar* const* vars,
01199 const IntVar* const* secondary_vars,
01200 int size)
01201 : PathOperator(vars, secondary_vars, size, 1) {}
01202 virtual ~MakeInactiveOperator() {}
01203 virtual bool MakeNeighbor() {
01204 const int64 base = BaseNode(0);
01205 if (IsPathEnd(base)) {
01206 return false;
01207 }
01208 return MakeChainInactive(base, Next(base));
01209 }
01210 };
01211
01212
01213
01214
01215
01216
01217
01218
01219
01220 class SwapActiveOperator : public BaseInactiveNodeToPathOperator {
01221 public:
01222 SwapActiveOperator(const IntVar* const* vars,
01223 const IntVar* const* secondary_vars,
01224 int size)
01225 : BaseInactiveNodeToPathOperator(vars, secondary_vars, size, 1) {}
01226 virtual ~SwapActiveOperator() {}
01227 virtual bool MakeNeighbor();
01228 };
01229
01230 bool SwapActiveOperator::MakeNeighbor() {
01231 const int64 base = BaseNode(0);
01232 if (IsPathEnd(base)) {
01233 return false;
01234 }
01235 return MakeChainInactive(base, Next(base))
01236 && MakeActive(GetInactiveNode(), base);
01237 }
01238
01239
01240
01241
01242
01243
01244
01245
01246
01247
01248
01249
01250
01251
01252 class ExtendedSwapActiveOperator : public BaseInactiveNodeToPathOperator {
01253 public:
01254 ExtendedSwapActiveOperator(const IntVar* const* vars,
01255 const IntVar* const* secondary_vars,
01256 int size)
01257 : BaseInactiveNodeToPathOperator(vars, secondary_vars, size, 2) {}
01258 virtual ~ExtendedSwapActiveOperator() {}
01259 virtual bool MakeNeighbor();
01260 };
01261
01262 bool ExtendedSwapActiveOperator::MakeNeighbor() {
01263 const int64 base0 = BaseNode(0);
01264 if (IsPathEnd(base0)) {
01265 return false;
01266 }
01267 const int64 base1 = BaseNode(1);
01268 if (IsPathEnd(base1)) {
01269 return false;
01270 }
01271 if (Next(base0) == base1) {
01272 return false;
01273 }
01274 return MakeChainInactive(base0, Next(base0))
01275 && MakeActive(GetInactiveNode(), base1);
01276 }
01277
01278
01279
01280
01281
01282
01283
01284
01285
01286
01287 class TSPOpt : public PathOperator {
01288 public:
01289 TSPOpt(const IntVar* const* vars,
01290 const IntVar* const* secondary_vars,
01291 int size,
01292 Solver::IndexEvaluator3* evaluator,
01293 int chain_length);
01294 virtual ~TSPOpt() {}
01295 virtual bool MakeNeighbor();
01296 private:
01297 std::vector<std::vector<int64> > cost_;
01298 HamiltonianPathSolver<int64> hamiltonian_path_solver_;
01299 scoped_ptr<Solver::IndexEvaluator3> evaluator_;
01300 const int chain_length_;
01301 };
01302
01303 TSPOpt::TSPOpt(const IntVar* const* vars,
01304 const IntVar* const* secondary_vars,
01305 int size,
01306 Solver::IndexEvaluator3* evaluator,
01307 int chain_length)
01308 : PathOperator(vars, secondary_vars, size, 1),
01309 hamiltonian_path_solver_(cost_),
01310 evaluator_(evaluator),
01311 chain_length_(chain_length) {}
01312
01313 bool TSPOpt::MakeNeighbor() {
01314 std::vector<int64> nodes;
01315 int64 chain_end = BaseNode(0);
01316 for (int i = 0; i < chain_length_ + 1; ++i) {
01317 nodes.push_back(chain_end);
01318 if (IsPathEnd(chain_end)) {
01319 break;
01320 }
01321 chain_end = Next(chain_end);
01322 }
01323 if (nodes.size() <= 3) {
01324 return false;
01325 }
01326 int64 chain_path = Path(BaseNode(0));
01327 const int size = nodes.size() - 1;
01328 cost_.resize(size);
01329 for (int i = 0; i < size; ++i) {
01330 cost_[i].resize(size);
01331 cost_[i][0] = evaluator_->Run(nodes[i], nodes[size], chain_path);
01332 for (int j = 1; j < size; ++j) {
01333 cost_[i][j] = evaluator_->Run(nodes[i], nodes[j], chain_path);
01334 }
01335 }
01336 hamiltonian_path_solver_.ChangeCostMatrix(cost_);
01337 std::vector<PathNodeIndex> path;
01338 hamiltonian_path_solver_.TravelingSalesmanPath(&path);
01339 CHECK_EQ(size + 1, path.size());
01340 for (int i = 0; i < size - 1; ++i) {
01341 SetNext(nodes[path[i]], nodes[path[i + 1]], chain_path);
01342 }
01343 SetNext(nodes[path[size - 1]], nodes[size], chain_path);
01344 return true;
01345 }
01346
01347
01348
01349
01350
01351
01352
01353
01354
01355 class TSPLns : public PathOperator {
01356 public:
01357 TSPLns(const IntVar* const* vars,
01358 const IntVar* const* secondary_vars,
01359 int size,
01360 Solver::IndexEvaluator3* evaluator,
01361 int tsp_size);
01362 virtual ~TSPLns() {}
01363 virtual bool MakeNeighbor();
01364
01365 protected:
01366 virtual bool MakeOneNeighbor();
01367
01368 private:
01369 std::vector<std::vector<int64> > cost_;
01370 HamiltonianPathSolver<int64> hamiltonian_path_solver_;
01371 scoped_ptr<Solver::IndexEvaluator3> evaluator_;
01372 const int tsp_size_;
01373 ACMRandom rand_;
01374 };
01375
01376 TSPLns::TSPLns(const IntVar* const* vars,
01377 const IntVar* const* secondary_vars,
01378 int size,
01379 Solver::IndexEvaluator3* evaluator,
01380 int tsp_size)
01381 : PathOperator(vars, secondary_vars, size, 1),
01382 hamiltonian_path_solver_(cost_),
01383 evaluator_(evaluator),
01384 tsp_size_(tsp_size),
01385 rand_(ACMRandom::HostnamePidTimeSeed()) {
01386 cost_.resize(tsp_size_);
01387 for (int i = 0; i < tsp_size_; ++i) {
01388 cost_[i].resize(tsp_size_);
01389 }
01390 }
01391
01392 bool TSPLns::MakeOneNeighbor() {
01393 while (true) {
01394 if (PathOperator::MakeOneNeighbor()) {
01395 return true;
01396 }
01397 }
01398 return false;
01399 }
01400
01401 bool TSPLns::MakeNeighbor() {
01402 const int64 base_node = BaseNode(0);
01403 if (IsPathEnd(base_node)) {
01404 return false;
01405 }
01406 std::vector<int64> nodes;
01407 for (int64 node = StartNode(0); !IsPathEnd(node); node = Next(node)) {
01408 nodes.push_back(node);
01409 }
01410 if (nodes.size() <= tsp_size_) {
01411 return false;
01412 }
01413
01414
01415 hash_set<int64> breaks_set;
01416
01417 breaks_set.insert(base_node);
01418 while (breaks_set.size() < tsp_size_) {
01419 const int64 one_break = nodes[rand_.Uniform(nodes.size())];
01420 if (!ContainsKey(breaks_set, one_break)) {
01421 breaks_set.insert(one_break);
01422 }
01423 }
01424 CHECK_EQ(breaks_set.size(), tsp_size_);
01425
01426
01427
01428
01429 std::vector<int> breaks;
01430 std::vector<int64> meta_node_costs;
01431 int64 cost = 0;
01432 int64 node = StartNode(0);
01433 int64 node_path = Path(node);
01434 while (!IsPathEnd(node)) {
01435 int64 next = Next(node);
01436 if (ContainsKey(breaks_set, node)) {
01437 breaks.push_back(node);
01438 meta_node_costs.push_back(cost);
01439 cost = 0;
01440 } else {
01441 cost += evaluator_->Run(node, next, node_path);
01442 }
01443 node = next;
01444 }
01445 meta_node_costs[0] += cost;
01446 CHECK_EQ(breaks.size(), tsp_size_);
01447
01448 CHECK_EQ(meta_node_costs.size(), tsp_size_);
01449 for (int i = 0; i < tsp_size_; ++i) {
01450 cost_[i][0] = meta_node_costs[i]
01451 + evaluator_->Run(breaks[i], Next(breaks[tsp_size_ - 1]), node_path);
01452 for (int j = 1; j < tsp_size_; ++j) {
01453 cost_[i][j] = meta_node_costs[i]
01454 + evaluator_->Run(breaks[i], Next(breaks[j - 1]), node_path);
01455 }
01456 cost_[i][i] = 0;
01457 }
01458
01459 hamiltonian_path_solver_.ChangeCostMatrix(cost_);
01460 std::vector<PathNodeIndex> path;
01461 hamiltonian_path_solver_.TravelingSalesmanPath(&path);
01462 bool nochange = true;
01463 for (int i = 0; i < path.size() - 1; ++i) {
01464 if (path[i] != i) {
01465 nochange = false;
01466 break;
01467 }
01468 }
01469 if (nochange) {
01470 return false;
01471 }
01472 CHECK_EQ(0, path[path.size() - 1]);
01473 for (int i = 0; i < tsp_size_ - 1; ++i) {
01474 SetNext(breaks[path[i]], OldNext(breaks[path[i + 1] - 1]), node_path);
01475 }
01476 SetNext(breaks[path[tsp_size_ - 1]],
01477 OldNext(breaks[tsp_size_ - 1]),
01478 node_path);
01479 return true;
01480 }
01481
01482
01483
01484
01485
01486
01487
01488
01489
01490 class NearestNeighbors {
01491 public:
01492 NearestNeighbors(Solver::IndexEvaluator3* evaluator,
01493 const PathOperator& path_operator,
01494 int size);
01495 void Initialize();
01496 const std::vector<int>& Neighbors(int index) const;
01497 private:
01498 void ComputeNearest(int row);
01499 static void Pivot(int start,
01500 int end,
01501 int* neighbors,
01502 int64* row,
01503 int* index);
01504 static void Swap(int i, int j, int* neighbors, int64* row);
01505
01506 std::vector<std::vector<int> > neighbors_;
01507 Solver::IndexEvaluator3* evaluator_;
01508 const PathOperator& path_operator_;
01509 const int size_;
01510 bool initialized_;
01511
01512 DISALLOW_COPY_AND_ASSIGN(NearestNeighbors);
01513 };
01514
01515 NearestNeighbors::NearestNeighbors(Solver::IndexEvaluator3* evaluator,
01516 const PathOperator& path_operator,
01517 int size)
01518 : evaluator_(evaluator),
01519 path_operator_(path_operator),
01520 size_(size),
01521 initialized_(false) {}
01522
01523 void NearestNeighbors::Initialize() {
01524
01525 if (!initialized_) {
01526 initialized_ = true;
01527 for (int i = 0; i < path_operator_.number_of_nexts(); ++i) {
01528 neighbors_.push_back(std::vector<int>());
01529 ComputeNearest(i);
01530 }
01531 }
01532 }
01533
01534 const std::vector<int>& NearestNeighbors::Neighbors(int index) const {
01535 return neighbors_[index];
01536 }
01537
01538 void NearestNeighbors::ComputeNearest(int row) {
01539
01540 const int path = path_operator_.Path(row);
01541 const IntVar* var = path_operator_.Var(row);
01542 const int64 var_min = var->Min();
01543 const int var_size = var->Max() - var_min + 1;
01544 scoped_array<int> neighbors(new int[var_size]);
01545 scoped_array<int64> row_data(new int64[var_size]);
01546 for (int i = 0; i < var_size; ++i) {
01547 const int index = i + var_min;
01548 neighbors[i] = index;
01549 row_data[i] = evaluator_->Run(row, index, path);
01550 }
01551
01552 if (var_size > size_) {
01553 int start = 0;
01554 int end = var_size;
01555 int size = size_;
01556 while (size > 0) {
01557 int index = (end - start) / 2;
01558 Pivot(start, end, neighbors.get(), row_data.get(), &index);
01559 if (index - start >= size) {
01560 end = index;
01561 } else {
01562 start = index + 1;
01563 size -= start;
01564 }
01565 }
01566 }
01567
01568
01569 for (int i = 0; i < std::min(size_, var_size); ++i) {
01570 neighbors_[row].push_back(neighbors[i]);
01571 std::sort(neighbors_[row].begin(), neighbors_[row].end());
01572 }
01573 }
01574
01575 void NearestNeighbors::Pivot(int start,
01576 int end,
01577 int* neighbors,
01578 int64* row,
01579 int* index) {
01580 Swap(start, *index, neighbors, row);
01581 int j = start;
01582 for (int i = start + 1; i < end; ++i) {
01583 if (row[i] < row[j]) {
01584 Swap(j, i, neighbors, row);
01585 ++j;
01586 Swap(i, j, neighbors, row);
01587 }
01588 }
01589 *index = j;
01590 }
01591
01592 void NearestNeighbors::Swap(int i, int j, int* neighbors, int64* row) {
01593 const int64 row_i = row[i];
01594 const int neighbor_i = neighbors[i];
01595 row[i] = row[j];
01596 neighbors[i] = neighbors[j];
01597 row[j] = row_i;
01598 neighbors[j] = neighbor_i;
01599 }
01600
01601 class LinKernighan : public PathOperator {
01602 public:
01603 LinKernighan(const IntVar* const* vars,
01604 const IntVar* const* secondary_vars,
01605 int size,
01606 Solver::IndexEvaluator3* evaluator,
01607 bool owner,
01608 bool topt);
01609 virtual ~LinKernighan();
01610 virtual bool MakeNeighbor();
01611 private:
01612 virtual void OnNodeInitialization();
01613
01614 static const int kNeighbors;
01615
01616 bool InFromOut(int64 in_i, int64 in_j, int64* out, int64* gain);
01617
01618 Solver::IndexEvaluator3* const evaluator_;
01619 bool owner_;
01620 NearestNeighbors neighbors_;
01621 hash_set<int64> marked_;
01622 const bool topt_;
01623 };
01624
01625
01626
01627
01628
01629 LinKernighan::LinKernighan(const IntVar* const* vars,
01630 const IntVar* const* secondary_vars,
01631 int size,
01632 Solver::IndexEvaluator3* evaluator,
01633 bool owner,
01634 bool topt)
01635 : PathOperator(vars, secondary_vars, size, 1),
01636 evaluator_(evaluator),
01637 owner_(owner),
01638 neighbors_(evaluator, *this, kNeighbors),
01639 topt_(topt) {}
01640
01641 LinKernighan::~LinKernighan() {
01642 if (owner_) {
01643 delete evaluator_;
01644 }
01645 }
01646
01647 void LinKernighan::OnNodeInitialization() {
01648 neighbors_.Initialize();
01649 }
01650
01651 bool LinKernighan::MakeNeighbor() {
01652 marked_.clear();
01653 int64 node = BaseNode(0);
01654 if (IsPathEnd(node)) return false;
01655 int64 path = Path(node);
01656 int64 base = node;
01657 int64 next = Next(node);
01658 if (IsPathEnd(next)) return false;
01659 int64 out = -1;
01660 int64 gain = 0;
01661 marked_.insert(node);
01662 if (topt_) {
01663 if (InFromOut(node, next, &out, &gain)) {
01664 marked_.insert(next);
01665 marked_.insert(out);
01666 const int64 node1 = out;
01667 if (IsPathEnd(node1)) return false;
01668 const int64 next1 = Next(node1);
01669 if (IsPathEnd(next1)) return false;
01670 if (InFromOut(node1, next1, &out, &gain)) {
01671 marked_.insert(next1);
01672 marked_.insert(out);
01673 if (MoveChain(out, node1, node)) {
01674 const int64 next_out = Next(out);
01675 int64 in_cost = evaluator_->Run(node, next_out, path);
01676 int64 out_cost = evaluator_->Run(out, next_out, path);
01677 if (gain - in_cost + out_cost > 0)
01678 return true;
01679 node = out;
01680 if (IsPathEnd(node)) {
01681 return false;
01682 }
01683 next = next_out;
01684 if (IsPathEnd(next)) {
01685 return false;
01686 }
01687 } else {
01688 return false;
01689 }
01690 } else {
01691 return false;
01692 }
01693 } else {
01694 return false;
01695 }
01696 }
01697
01698 while (InFromOut(node, next, &out, &gain)) {
01699 marked_.insert(next);
01700 marked_.insert(out);
01701 int64 chain_last;
01702 if (!ReverseChain(node, out, &chain_last)) {
01703 return false;
01704 }
01705 int64 in_cost = evaluator_->Run(base, chain_last, path);
01706 int64 out_cost = evaluator_->Run(chain_last, out, path);
01707 if (gain - in_cost + out_cost > 0) {
01708 return true;
01709 }
01710 node = chain_last;
01711 if (IsPathEnd(node)) {
01712 return false;
01713 }
01714 next = out;
01715 if (IsPathEnd(next)) {
01716 return false;
01717 }
01718 }
01719 return false;
01720 }
01721
01722 const int LinKernighan::kNeighbors = 5 + 1;
01723
01724 bool LinKernighan::InFromOut(int64 in_i, int64 in_j, int64* out, int64* gain) {
01725 const std::vector<int>& nexts = neighbors_.Neighbors(in_j);
01726 int64 best_gain = kint64min;
01727 int64 path = Path(in_i);
01728 int64 out_cost = evaluator_->Run(in_i, in_j, path);
01729 const int64 current_gain = *gain + out_cost;
01730 for (int k = 0; k < nexts.size(); ++k) {
01731 const int64 next = nexts[k];
01732 if (next != in_j) {
01733 int64 in_cost = evaluator_->Run(in_j, next, path);
01734 int64 new_gain = current_gain - in_cost;
01735 if (new_gain > 0
01736 && next != Next(in_j)
01737 && marked_.count(in_j) == 0
01738 && marked_.count(next) == 0) {
01739 if (best_gain < new_gain) {
01740 *out = next;
01741 best_gain = new_gain;
01742 }
01743 }
01744 }
01745 }
01746 *gain = best_gain;
01747 return (best_gain > kint64min);
01748 }
01749
01750
01751
01752
01753
01754 class PathLNS : public PathOperator {
01755 public:
01756 PathLNS(const IntVar* const* vars,
01757 const IntVar* const* secondary_vars,
01758 int size,
01759 int number_of_chunks,
01760 int chunk_size,
01761 bool unactive_fragments)
01762 : PathOperator(vars, secondary_vars, size, number_of_chunks),
01763 number_of_chunks_(number_of_chunks),
01764 chunk_size_(chunk_size),
01765 unactive_fragments_(unactive_fragments) {
01766 CHECK_GT(chunk_size_, 0);
01767 }
01768 virtual ~PathLNS() {}
01769 virtual bool MakeNeighbor();
01770 private:
01771 void DeactivateChain(int64 node0);
01772 void DeactivateUnactives();
01773
01774 const int number_of_chunks_;
01775 const int chunk_size_;
01776 const bool unactive_fragments_;
01777 };
01778
01779 bool PathLNS::MakeNeighbor() {
01780 for (int i = 0; i < number_of_chunks_; ++i) {
01781 DeactivateChain(BaseNode(i));
01782 }
01783 DeactivateUnactives();
01784 return true;
01785 }
01786
01787 void PathLNS::DeactivateChain(int64 node) {
01788 for (int i = 0, current = node;
01789 i < chunk_size_ && !IsPathEnd(current);
01790 ++i, current = Next(current)) {
01791 Deactivate(current);
01792 if (!ignore_path_vars_) {
01793 Deactivate(number_of_nexts_ + current);
01794 }
01795 }
01796 }
01797
01798 void PathLNS::DeactivateUnactives() {
01799 if (unactive_fragments_) {
01800 for (int i = 0; i < Size(); ++i) {
01801 if (IsInactive(i)) {
01802 Deactivate(i);
01803 if (!ignore_path_vars_) {
01804 Deactivate(number_of_nexts_ + i);
01805 }
01806 }
01807 }
01808 }
01809 }
01810
01811
01812
01813 class NeighborhoodLimit : public LocalSearchOperator {
01814 public:
01815 NeighborhoodLimit(LocalSearchOperator* const op, int64 limit)
01816 : operator_(op), limit_(limit), next_neighborhood_calls_(0) {
01817 CHECK_NOTNULL(op);
01818 CHECK_GT(limit, 0);
01819 }
01820
01821 virtual void Start(const Assignment* assignment) {
01822 next_neighborhood_calls_ = 0;
01823 operator_->Start(assignment);
01824 }
01825
01826 virtual bool MakeNextNeighbor(Assignment* delta, Assignment* deltadelta) {
01827 if (next_neighborhood_calls_ >= limit_) {
01828 return false;
01829 }
01830 ++next_neighborhood_calls_;
01831 return operator_->MakeNextNeighbor(delta, deltadelta);
01832 }
01833
01834 private:
01835 LocalSearchOperator* const operator_;
01836 const int64 limit_;
01837 int64 next_neighborhood_calls_;
01838 };
01839 }
01840
01841 LocalSearchOperator* Solver::MakeNeighborhoodLimit(
01842 LocalSearchOperator* const op, int64 limit) {
01843 return RevAlloc(new NeighborhoodLimit(op, limit));
01844 }
01845
01846
01847
01848 namespace {
01849 class CompoundOperator : public LocalSearchOperator {
01850 public:
01851 CompoundOperator(
01852 const std::vector<LocalSearchOperator*>& operators,
01853 ResultCallback2<int64, int, int>* const evaluator);
01854 virtual ~CompoundOperator() {}
01855 virtual void Start(const Assignment* assignment);
01856 virtual bool MakeNextNeighbor(Assignment* delta, Assignment* deltadelta);
01857
01858 private:
01859 class OperatorComparator {
01860 public:
01861 OperatorComparator(ResultCallback2<int64, int, int>* const evaluator,
01862 int active_operator)
01863 : evaluator_(evaluator), active_operator_(active_operator) {
01864 evaluator_->CheckIsRepeatable();
01865 }
01866 bool operator() (int lhs, int rhs) const {
01867 const int64 lhs_value = Evaluate(lhs);
01868 const int64 rhs_value = Evaluate(rhs);
01869 return lhs_value < rhs_value || (lhs_value == rhs_value && lhs < rhs);
01870 }
01871
01872 private:
01873 int64 Evaluate(int operator_index) const {
01874 return evaluator_->Run(active_operator_, operator_index);
01875 }
01876
01877 ResultCallback2<int64, int, int>* const evaluator_;
01878 const int active_operator_;
01879 };
01880
01881 int64 index_;
01882 int64 size_;
01883 scoped_array<LocalSearchOperator*> operators_;
01884 scoped_array<int> operator_indices_;
01885 scoped_ptr<ResultCallback2<int64, int, int> > evaluator_;
01886 };
01887
01888 CompoundOperator::CompoundOperator(
01889 const std::vector<LocalSearchOperator*>& operators,
01890 ResultCallback2<int64, int, int>* const evaluator)
01891 : index_(0),
01892 size_(0),
01893 operators_(NULL),
01894 operator_indices_(NULL),
01895 evaluator_(evaluator) {
01896 for (int i = 0; i < operators.size(); ++i) {
01897 if (operators[i] != NULL) {
01898 ++size_;
01899 }
01900 }
01901 operators_.reset(new LocalSearchOperator*[size_]);
01902 operator_indices_.reset(new int[size_]);
01903 int index = 0;
01904 for (int i = 0; i < operators.size(); ++i) {
01905 if (operators[i] != NULL) {
01906 operators_[index] = operators[i];
01907 operator_indices_[index] = index;
01908 ++index;
01909 }
01910 }
01911 }
01912
01913 void CompoundOperator::Start(const Assignment* assignment) {
01914 if (size_ > 0) {
01915 for (int i = 0; i < size_; ++i) {
01916 operators_[i]->Start(assignment);
01917 }
01918 OperatorComparator comparator(evaluator_.get(), operator_indices_[index_]);
01919 std::sort(operator_indices_.get(),
01920 operator_indices_.get() + size_,
01921 comparator);
01922 index_ = 0;
01923 }
01924 }
01925
01926 bool CompoundOperator::MakeNextNeighbor(Assignment* delta,
01927 Assignment* deltadelta) {
01928 if (size_ > 0) {
01929 do {
01930
01931
01932 if (operators_[operator_indices_[index_]]->MakeNextNeighbor(delta,
01933 deltadelta)) {
01934 return true;
01935 }
01936 ++index_;
01937 if (index_ == size_) {
01938 index_ = 0;
01939 }
01940 } while (index_ != 0);
01941 }
01942 return false;
01943 }
01944
01945 int64 CompoundOperatorNoRestart(int size,
01946 int active_index,
01947 int operator_index) {
01948 if (operator_index < active_index) {
01949 return size + operator_index - active_index;
01950 } else {
01951 return operator_index - active_index;
01952 }
01953 }
01954
01955 int64 CompoundOperatorRestart(int active_index, int operator_index) {
01956 return 0;
01957 }
01958 }
01959
01960 LocalSearchOperator* Solver::ConcatenateOperators(
01961 const std::vector<LocalSearchOperator*>& ops) {
01962 return ConcatenateOperators(ops, false);
01963 }
01964
01965 LocalSearchOperator* Solver::ConcatenateOperators(
01966 const std::vector<LocalSearchOperator*>& ops,
01967 bool restart) {
01968 if (restart) {
01969 return ConcatenateOperators(
01970 ops,
01971 NewPermanentCallback(&CompoundOperatorRestart));
01972 } else {
01973 return ConcatenateOperators(
01974 ops,
01975 NewPermanentCallback(&CompoundOperatorNoRestart,
01976 static_cast<int>(ops.size())));
01977 }
01978 }
01979
01980 LocalSearchOperator* Solver::ConcatenateOperators(
01981 const std::vector<LocalSearchOperator*>& ops,
01982 ResultCallback2<int64, int, int>* const evaluator) {
01983 return RevAlloc(new CompoundOperator(ops, evaluator));
01984 }
01985
01986 namespace {
01987 class RandomCompoundOperator : public LocalSearchOperator {
01988 public:
01989 explicit RandomCompoundOperator(
01990 const std::vector<LocalSearchOperator*>& operators);
01991 virtual ~RandomCompoundOperator() {}
01992 virtual void Start(const Assignment* assignment);
01993 virtual bool MakeNextNeighbor(Assignment* delta, Assignment* deltadelta);
01994 private:
01995 const int size_;
01996 scoped_array<LocalSearchOperator*> operators_;
01997 };
01998
01999 void RandomCompoundOperator::Start(const Assignment* assignment) {
02000 for (int i = 0; i < size_; ++i) {
02001 operators_[i]->Start(assignment);
02002 }
02003 }
02004
02005 RandomCompoundOperator::RandomCompoundOperator(
02006 const std::vector<LocalSearchOperator*>& operators)
02007 : size_(operators.size()),
02008 operators_(new LocalSearchOperator*[size_]) {
02009 for (int i = 0; i < size_; ++i) {
02010 operators_[i] = operators[i];
02011 }
02012 }
02013
02014 bool RandomCompoundOperator::MakeNextNeighbor(Assignment* delta,
02015 Assignment* deltadelta) {
02016 std::vector<int> indices(size_);
02017 for (int i = 0; i < size_; ++i) {
02018 indices[i] = i;
02019 }
02020 random_shuffle(indices.begin(), indices.end());
02021 for (int i = 0; i < size_; ++i) {
02022 if (operators_[indices[i]]->MakeNextNeighbor(delta, deltadelta)) {
02023 return true;
02024 }
02025 }
02026 return false;
02027 }
02028 }
02029
02030 LocalSearchOperator* Solver::RandomConcatenateOperators(
02031 const std::vector<LocalSearchOperator*>& ops) {
02032 return RevAlloc(new RandomCompoundOperator(ops));
02033 }
02034
02035
02036
02037 LocalSearchOperator* Solver::MakeOperator(const std::vector<IntVar*>& vars,
02038 Solver::LocalSearchOperators op) {
02039 return MakeOperator(vars.data(), vars.size(), op);
02040 }
02041
02042 LocalSearchOperator* Solver::MakeOperator(const IntVar* const* vars,
02043 int size,
02044 Solver::LocalSearchOperators op) {
02045 return MakeOperator(vars, NULL, size, op);
02046 }
02047
02048 LocalSearchOperator* Solver::MakeOperator(const std::vector<IntVar*>& vars,
02049 const std::vector<IntVar*>& secondary_vars,
02050 Solver::LocalSearchOperators op) {
02051 return MakeOperator(vars.data(), secondary_vars.data(), vars.size(), op);
02052 }
02053
02054 LocalSearchOperator* Solver::MakeOperator(const IntVar* const* vars,
02055 const IntVar* const* secondary_vars,
02056 int size,
02057 Solver::LocalSearchOperators op) {
02058 LocalSearchOperator* result = NULL;
02059 switch (op) {
02060 case Solver::TWOOPT: {
02061 result = RevAlloc(new TwoOpt(vars, secondary_vars, size));
02062 break;
02063 }
02064 case Solver::OROPT: {
02065 std::vector<LocalSearchOperator*> operators;
02066 for (int i = 1; i < 4; ++i)
02067 operators.push_back(RevAlloc(new Relocate(vars,
02068 secondary_vars,
02069 size,
02070 i,
02071 true)));
02072 result = ConcatenateOperators(operators);
02073 break;
02074 }
02075 case Solver::RELOCATE: {
02076 result = RevAlloc(new Relocate(vars, secondary_vars, size));
02077 break;
02078 }
02079 case Solver::EXCHANGE: {
02080 result = RevAlloc(new Exchange(vars, secondary_vars, size));
02081 break;
02082 }
02083 case Solver::CROSS: {
02084 result = RevAlloc(new Cross(vars, secondary_vars, size));
02085 break;
02086 }
02087 case Solver::MAKEACTIVE: {
02088 result = RevAlloc(new MakeActiveOperator(vars, secondary_vars, size));
02089 break;
02090 }
02091 case Solver::MAKEINACTIVE: {
02092 result = RevAlloc(new MakeInactiveOperator(vars, secondary_vars, size));
02093 break;
02094 }
02095 case Solver::SWAPACTIVE: {
02096 result = RevAlloc(new SwapActiveOperator(vars, secondary_vars, size));
02097 break;
02098 }
02099 case Solver::EXTENDEDSWAPACTIVE: {
02100 result = RevAlloc(
02101 new ExtendedSwapActiveOperator(vars, secondary_vars, size));
02102 break;
02103 }
02104 case Solver::PATHLNS: {
02105 result = RevAlloc(new PathLNS(vars, secondary_vars, size, 2, 3, false));
02106 break;
02107 }
02108 case Solver::UNACTIVELNS: {
02109 result = RevAlloc(new PathLNS(vars, secondary_vars, size, 1, 6, true));
02110 break;
02111 }
02112 case Solver::INCREMENT: {
02113 if (secondary_vars == NULL) {
02114 result = RevAlloc(new IncrementValue(vars, size));
02115 } else {
02116 LOG(FATAL) << "Operator " << op
02117 << " does not support secondary variables";
02118 }
02119 break;
02120 }
02121 case Solver::DECREMENT: {
02122 if (secondary_vars == NULL) {
02123 result = RevAlloc(new DecrementValue(vars, size));
02124 } else {
02125 LOG(FATAL) << "Operator " << op
02126 << " does not support secondary variables";
02127 }
02128 break;
02129 }
02130 case Solver::SIMPLELNS: {
02131 if (secondary_vars == NULL) {
02132 result = RevAlloc(new SimpleLNS(vars, size, 1));
02133 } else {
02134 LOG(FATAL) << "Operator " << op
02135 << " does not support secondary variables";
02136 }
02137 break;
02138 }
02139 default:
02140 LOG(FATAL) << "Unknown operator " << op;
02141 }
02142 return result;
02143 }
02144
02145 LocalSearchOperator* Solver::MakeOperator(
02146 const std::vector<IntVar*>& vars,
02147 Solver::IndexEvaluator3* const evaluator,
02148 Solver::EvaluatorLocalSearchOperators op) {
02149 return MakeOperator(vars.data(), vars.size(), evaluator, op);
02150 }
02151
02152 LocalSearchOperator* Solver::MakeOperator(
02153 const IntVar* const* vars,
02154 int size,
02155 Solver::IndexEvaluator3* const evaluator,
02156 Solver::EvaluatorLocalSearchOperators op) {
02157 return MakeOperator(vars, NULL, size, evaluator, op);
02158 }
02159
02160 LocalSearchOperator* Solver::MakeOperator(
02161 const std::vector<IntVar*>& vars,
02162 const std::vector<IntVar*>& secondary_vars,
02163 Solver::IndexEvaluator3* const evaluator,
02164 Solver::EvaluatorLocalSearchOperators op) {
02165 return MakeOperator(vars.data(),
02166 secondary_vars.data(),
02167 vars.size(),
02168 evaluator,
02169 op);
02170 }
02171
02172 LocalSearchOperator* Solver::MakeOperator(
02173 const IntVar* const* vars,
02174 const IntVar* const* secondary_vars,
02175 int size,
02176 Solver::IndexEvaluator3* const evaluator,
02177 Solver::EvaluatorLocalSearchOperators op) {
02178 LocalSearchOperator* result = NULL;
02179 switch (op) {
02180 case Solver::LK: {
02181 std::vector<LocalSearchOperator*> operators;
02182 operators.push_back(
02183 RevAlloc(new LinKernighan(vars,
02184 secondary_vars,
02185 size,
02186 evaluator,
02187 true, false)));
02188 operators.push_back(
02189 RevAlloc(new LinKernighan(vars,
02190 secondary_vars,
02191 size,
02192 evaluator,
02193 false, true)));
02194 result = ConcatenateOperators(operators);
02195 break;
02196 }
02197 case Solver::TSPOPT: {
02198 result = RevAlloc(new TSPOpt(vars, secondary_vars, size, evaluator,
02199 FLAGS_cp_local_search_tsp_opt_size));
02200 break;
02201 }
02202 case Solver::TSPLNS: {
02203 result = RevAlloc(new TSPLns(vars, secondary_vars, size, evaluator,
02204 FLAGS_cp_local_search_tsp_lns_size));
02205 break;
02206 }
02207 default:
02208 LOG(FATAL) << "Unknown operator " << op;
02209 }
02210 return result;
02211 }
02212
02213 namespace {
02214
02215
02216
02217 class LSOperation {
02218 public:
02219 LSOperation() {}
02220 virtual ~LSOperation() {}
02221 virtual void Init() = 0;
02222 virtual void Update(int64 update) = 0;
02223 virtual void Remove(int64 remove) = 0;
02224 virtual int64 value() = 0;
02225 virtual void set_value(int64 new_value) = 0;
02226 };
02227
02228 class SumOperation : public LSOperation {
02229 public:
02230 virtual void Init() { value_ = 0; }
02231 virtual void Update(int64 update) {
02232 value_ += update;
02233 }
02234 virtual void Remove(int64 remove) {
02235 value_ -= remove;
02236 }
02237 virtual int64 value() { return value_; }
02238 virtual void set_value(int64 new_value) { value_ = new_value; }
02239
02240 private:
02241 int64 value_;
02242 };
02243
02244 class ProductOperation : public LSOperation {
02245 public:
02246 virtual void Init() { value_ = 1; }
02247 virtual void Update(int64 update) {
02248 value_ *= update;
02249 }
02250 virtual void Remove(int64 remove) {
02251 if (remove != 0) {
02252 value_ /= remove;
02253 }
02254 }
02255 virtual int64 value() { return value_; }
02256 virtual void set_value(int64 new_value) { value_ = new_value; }
02257
02258 private:
02259 int64 value_;
02260 };
02261
02262 class MaxMinOperation : public LSOperation {
02263 public:
02264 explicit MaxMinOperation(bool max) : max_(max) {}
02265 virtual void Init() {
02266 values_set_.clear();
02267 }
02268 virtual void Update(int64 update) {
02269 values_set_.insert(update);
02270 }
02271 virtual void Remove(int64 remove) {
02272 values_set_.erase(remove);
02273 }
02274 virtual int64 value() {
02275 if (!values_set_.empty()) {
02276 if (max_) {
02277 return *values_set_.rbegin();
02278 } else {
02279 return *values_set_.begin();
02280 }
02281 } else {
02282 return 0;
02283 }
02284 }
02285 virtual void set_value(int64 new_value) {}
02286
02287 private:
02288 std::set<int64> values_set_;
02289 bool max_;
02290 };
02291
02292
02293
02294
02295 class VariableDomainFilter : public LocalSearchFilter {
02296 public:
02297 VariableDomainFilter() {}
02298 virtual ~VariableDomainFilter() {}
02299 virtual bool Accept(const Assignment* delta, const Assignment* deltadelta);
02300 virtual void Synchronize(const Assignment* assignment) {}
02301 };
02302
02303 bool VariableDomainFilter::Accept(const Assignment* delta,
02304 const Assignment* deltadelta) {
02305 const Assignment::IntContainer& container = delta->IntVarContainer();
02306 const int size = container.Size();
02307 for (int i = 0; i < size; ++i) {
02308 const IntVarElement& element = container.Element(i);
02309 if (element.Activated() && !element.Var()->Contains(element.Value())) {
02310 return false;
02311 }
02312 }
02313 return true;
02314 }
02315 }
02316
02317 LocalSearchFilter* Solver::MakeVariableDomainFilter() {
02318 return RevAlloc(new VariableDomainFilter());
02319 }
02320
02321
02322
02323 IntVarLocalSearchFilter::IntVarLocalSearchFilter(const IntVar* const* vars,
02324 int size)
02325 : vars_(NULL), values_(NULL), size_(0) {
02326 AddVars(vars, size);
02327 CHECK_GE(size_, 0);
02328 }
02329
02330 void IntVarLocalSearchFilter::AddVars(const IntVar* const* vars, int size) {
02331 if (size > 0) {
02332 for (int i = 0; i < size; ++i) {
02333 var_to_index_[vars[i]] = i + size_;
02334 }
02335 const int new_size = size_ + size;
02336 IntVar** new_vars = new IntVar*[new_size];
02337 if (size_ > 0) {
02338 memcpy(new_vars, vars_.get(), size_ * sizeof(*new_vars));
02339 }
02340 memcpy(new_vars + size_, vars, size * sizeof(*vars));
02341 vars_.reset(new_vars);
02342 values_.reset(new int64[new_size]);
02343 memset(values_.get(), 0, sizeof(int64) * new_size);
02344 size_ = new_size;
02345 }
02346 }
02347
02348 IntVarLocalSearchFilter::~IntVarLocalSearchFilter() {}
02349
02350 void IntVarLocalSearchFilter::Synchronize(const Assignment* assignment) {
02351 const Assignment::IntContainer& container = assignment->IntVarContainer();
02352 const int size = container.Size();
02353 for (int i = 0; i < size; ++i) {
02354 const IntVarElement& element = container.Element(i);
02355 const IntVar* var = element.Var();
02356 if (i < size_ && vars_[i] == var) {
02357 values_[i] = element.Value();
02358 } else {
02359 const int64 kUnallocated = -1;
02360 int64 index = kUnallocated;
02361 if (FindIndex(var, &index)) {
02362 values_[index] = element.Value();
02363 }
02364 }
02365 }
02366 OnSynchronize();
02367 }
02368
02369
02370
02371
02372
02373
02374
02375
02376
02377 namespace {
02378 class ObjectiveFilter : public IntVarLocalSearchFilter {
02379 public:
02380 ObjectiveFilter(const IntVar* const* vars,
02381 int size,
02382 const IntVar* const objective,
02383 Solver::LocalSearchFilterBound filter_enum,
02384 LSOperation* op);
02385 virtual ~ObjectiveFilter();
02386 virtual bool Accept(const Assignment* delta, const Assignment* deltadelta);
02387 virtual int64 SynchronizedElementValue(int64 index) = 0;
02388 virtual bool EvaluateElementValue(const Assignment::IntContainer& container,
02389 int index,
02390 int* container_index,
02391 int64* obj_value) = 0;
02392 virtual bool IsIncremental() const { return true; }
02393
02394 protected:
02395 const int primary_vars_size_;
02396 int64* const cache_;
02397 int64* const delta_cache_;
02398 const IntVar* const objective_;
02399 Solver::LocalSearchFilterBound filter_enum_;
02400 scoped_ptr<LSOperation> op_;
02401 int64 old_value_;
02402 int64 old_delta_value_;
02403 bool incremental_;
02404
02405 private:
02406 virtual void OnSynchronize();
02407 int64 Evaluate(const Assignment* delta,
02408 int64 current_value,
02409 const int64* const out_values,
02410 bool cache_delta_values);
02411 };
02412
02413 ObjectiveFilter::ObjectiveFilter(const IntVar* const* vars,
02414 int var_size,
02415 const IntVar* const objective,
02416 Solver::LocalSearchFilterBound filter_enum,
02417 LSOperation* op)
02418 : IntVarLocalSearchFilter(vars, var_size),
02419 primary_vars_size_(var_size),
02420 cache_(new int64[var_size]),
02421 delta_cache_(new int64[var_size]),
02422 objective_(objective),
02423 filter_enum_(filter_enum),
02424 op_(op),
02425 old_value_(0),
02426 old_delta_value_(0),
02427 incremental_(false) {
02428 CHECK(op_ != NULL);
02429 for (int i = 0; i < Size(); ++i) {
02430 cache_[i] = 0;
02431 delta_cache_[i] = 0;
02432 }
02433 op_->Init();
02434 old_value_ = op_->value();
02435 }
02436
02437 ObjectiveFilter::~ObjectiveFilter() {
02438 delete [] cache_;
02439 delete [] delta_cache_;
02440 }
02441
02442 bool ObjectiveFilter::Accept(const Assignment* delta,
02443 const Assignment* deltadelta) {
02444 if (delta == NULL) {
02445 return false;
02446 }
02447 int64 value = 0;
02448 if (!deltadelta->Empty()) {
02449 if (!incremental_) {
02450 value = Evaluate(delta, old_value_, cache_, true);
02451 } else {
02452 value = Evaluate(deltadelta, old_delta_value_, delta_cache_, true);
02453 }
02454 incremental_ = true;
02455 } else {
02456 if (incremental_) {
02457 for (int i = 0; i < primary_vars_size_; ++i) {
02458 delta_cache_[i] = cache_[i];
02459 }
02460 old_delta_value_ = old_value_;
02461 }
02462 incremental_ = false;
02463 value = Evaluate(delta, old_value_, cache_, false);
02464 }
02465 old_delta_value_ = value;
02466 int64 var_min = objective_->Min();
02467 int64 var_max = objective_->Max();
02468 if (delta->Objective() == objective_) {
02469 var_min = std::max(var_min, delta->ObjectiveMin());
02470 var_max = std::min(var_max, delta->ObjectiveMax());
02471 }
02472 switch (filter_enum_) {
02473 case Solver::LE: {
02474 return value <= var_max;
02475 }
02476 case Solver::GE: {
02477 return value >= var_min;
02478 }
02479 case Solver::EQ: {
02480 return value <= var_max && value >= var_min;
02481 }
02482 default: {
02483 LOG(ERROR) << "Unknown local search filter enum value";
02484 return false;
02485 }
02486 }
02487 }
02488
02489 void ObjectiveFilter::OnSynchronize() {
02490 op_->Init();
02491 for (int i = 0; i < primary_vars_size_; ++i) {
02492 const int64 obj_value = SynchronizedElementValue(i);
02493 cache_[i] = obj_value;
02494 delta_cache_[i] = obj_value;
02495 op_->Update(obj_value);
02496 }
02497 old_value_ = op_->value();
02498 old_delta_value_ = old_value_;
02499 incremental_ = false;
02500 }
02501
02502 int64 ObjectiveFilter::Evaluate(const Assignment* delta,
02503 int64 current_value,
02504 const int64* const out_values,
02505 bool cache_delta_values) {
02506 if (current_value == kint64max) return current_value;
02507 op_->set_value(current_value);
02508 const Assignment::IntContainer& container = delta->IntVarContainer();
02509 const int size = container.Size();
02510 for (int i = 0; i < size; ++i) {
02511 const IntVarElement& new_element = container.Element(i);
02512 const IntVar* var = new_element.Var();
02513 int64 index = -1;
02514 if (FindIndex(var, &index) && index < primary_vars_size_) {
02515 op_->Remove(out_values[index]);
02516 int64 obj_value = 0LL;
02517 if (EvaluateElementValue(container, index, &i, &obj_value)) {
02518 op_->Update(obj_value);
02519 if (cache_delta_values) {
02520 delta_cache_[index] = obj_value;
02521 }
02522 }
02523 }
02524 }
02525 return op_->value();
02526 }
02527
02528 class BinaryObjectiveFilter : public ObjectiveFilter {
02529 public:
02530 BinaryObjectiveFilter(const IntVar* const* vars,
02531 int size,
02532 Solver::IndexEvaluator2* values,
02533 const IntVar* const objective,
02534 Solver::LocalSearchFilterBound filter_enum,
02535 LSOperation* op);
02536 virtual ~BinaryObjectiveFilter() {}
02537 virtual int64 SynchronizedElementValue(int64 index);
02538 virtual bool EvaluateElementValue(const Assignment::IntContainer& container,
02539 int index,
02540 int* container_index,
02541 int64* obj_value);
02542 private:
02543 scoped_ptr<Solver::IndexEvaluator2> value_evaluator_;
02544 };
02545
02546 BinaryObjectiveFilter::BinaryObjectiveFilter(
02547 const IntVar* const* vars,
02548 int size,
02549 Solver::IndexEvaluator2* value_evaluator,
02550 const IntVar* const objective,
02551 Solver::LocalSearchFilterBound filter_enum,
02552 LSOperation* op)
02553 : ObjectiveFilter(vars, size, objective, filter_enum, op),
02554 value_evaluator_(value_evaluator) {
02555 value_evaluator_->CheckIsRepeatable();
02556 }
02557
02558 int64 BinaryObjectiveFilter::SynchronizedElementValue(int64 index) {
02559 return value_evaluator_->Run(index, Value(index));
02560 }
02561
02562 bool BinaryObjectiveFilter::EvaluateElementValue(
02563 const Assignment::IntContainer& container,
02564 int index,
02565 int* container_index,
02566 int64* obj_value) {
02567 const IntVarElement& element = container.Element(*container_index);
02568 if (element.Activated()) {
02569 *obj_value = value_evaluator_->Run(index, element.Value());
02570 return true;
02571 } else {
02572 const IntVar* var = element.Var();
02573 if (var->Bound()) {
02574 *obj_value = value_evaluator_->Run(index, var->Min());
02575 return true;
02576 }
02577 }
02578 return false;
02579 }
02580
02581 class TernaryObjectiveFilter : public ObjectiveFilter {
02582 public:
02583 TernaryObjectiveFilter(const IntVar* const* vars,
02584 const IntVar* const* secondary_vars,
02585 int size,
02586 Solver::IndexEvaluator3* value_evaluator,
02587 const IntVar* const objective,
02588 Solver::LocalSearchFilterBound filter_enum,
02589 LSOperation* op);
02590 virtual ~TernaryObjectiveFilter() {}
02591 virtual int64 SynchronizedElementValue(int64 index);
02592 bool EvaluateElementValue(const Assignment::IntContainer& container,
02593 int index,
02594 int* container_index,
02595 int64* obj_value);
02596 private:
02597 int secondary_vars_offset_;
02598 scoped_ptr<Solver::IndexEvaluator3> value_evaluator_;
02599 };
02600
02601 TernaryObjectiveFilter::TernaryObjectiveFilter(
02602 const IntVar* const* vars,
02603 const IntVar* const* secondary_vars,
02604 int var_size,
02605 Solver::IndexEvaluator3* value_evaluator,
02606 const IntVar* const objective,
02607 Solver::LocalSearchFilterBound filter_enum,
02608 LSOperation* op)
02609 : ObjectiveFilter(vars, var_size, objective, filter_enum, op),
02610 secondary_vars_offset_(var_size),
02611 value_evaluator_(value_evaluator) {
02612 value_evaluator_->CheckIsRepeatable();
02613 AddVars(secondary_vars, var_size);
02614 CHECK_GE(Size(), 0);
02615 }
02616
02617 int64 TernaryObjectiveFilter::SynchronizedElementValue(int64 index) {
02618 DCHECK_LT(index, secondary_vars_offset_);
02619 return value_evaluator_->Run(index,
02620 Value(index),
02621 Value(index + secondary_vars_offset_));
02622 }
02623
02624 bool TernaryObjectiveFilter::EvaluateElementValue(
02625 const Assignment::IntContainer& container,
02626 int index,
02627 int* container_index,
02628 int64* obj_value) {
02629 DCHECK_LT(index, secondary_vars_offset_);
02630 *obj_value = 0LL;
02631 const IntVarElement& element = container.Element(*container_index);
02632 const IntVar* secondary_var = Var(index + secondary_vars_offset_);
02633 if (element.Activated()) {
02634 const int64 value = element.Value();
02635 int hint_index = *container_index + 1;
02636 if (hint_index < container.Size()
02637 && secondary_var == container.Element(hint_index).Var()) {
02638 *obj_value =
02639 value_evaluator_->Run(index,
02640 value,
02641 container.Element(hint_index).Value());
02642 *container_index = hint_index;
02643 } else {
02644 *obj_value =
02645 value_evaluator_->Run(index,
02646 value,
02647 container.Element(secondary_var).Value());
02648 }
02649 return true;
02650 } else {
02651 const IntVar* var = element.Var();
02652 if (var->Bound() && secondary_var->Bound()) {
02653 *obj_value = value_evaluator_->Run(index,
02654 var->Min(),
02655 secondary_var->Min());
02656 return true;
02657 }
02658 }
02659 return false;
02660 }
02661
02662
02663
02664 LSOperation* OperationFromEnum(Solver::LocalSearchOperation op_enum) {
02665 LSOperation* operation = NULL;
02666 switch (op_enum) {
02667 case Solver::SUM: {
02668 operation = new SumOperation();
02669 break;
02670 }
02671 case Solver::PROD: {
02672 operation = new ProductOperation();
02673 break;
02674 }
02675 case Solver::MAX: {
02676 operation = new MaxMinOperation(true);
02677 break;
02678 }
02679 case Solver::MIN: {
02680 operation = new MaxMinOperation(false);
02681 break;
02682 }
02683 default:
02684 LOG(FATAL) << "Unknown operator " << op_enum;
02685 }
02686 return operation;
02687 }
02688 }
02689
02690 LocalSearchFilter* Solver::MakeLocalSearchObjectiveFilter(
02691 const IntVar* const* vars,
02692 int size,
02693 Solver::IndexEvaluator2* const values,
02694 const IntVar* const objective,
02695 Solver::LocalSearchFilterBound filter_enum,
02696 Solver::LocalSearchOperation op_enum) {
02697 return RevAlloc(new BinaryObjectiveFilter(vars,
02698 size,
02699 values,
02700 objective,
02701 filter_enum,
02702 OperationFromEnum(op_enum)));
02703 }
02704
02705 LocalSearchFilter* Solver::MakeLocalSearchObjectiveFilter(
02706 const std::vector<IntVar*>& vars,
02707 Solver::IndexEvaluator2* const values,
02708 const IntVar* const objective,
02709 Solver::LocalSearchFilterBound filter_enum,
02710 Solver::LocalSearchOperation op_enum) {
02711 return MakeLocalSearchObjectiveFilter(vars.data(),
02712 vars.size(),
02713 values,
02714 objective,
02715 filter_enum,
02716 op_enum);
02717 }
02718
02719 LocalSearchFilter* Solver::MakeLocalSearchObjectiveFilter(
02720 const IntVar* const* vars,
02721 const IntVar* const* secondary_vars,
02722 int size,
02723 Solver::IndexEvaluator3* const values,
02724 const IntVar* const objective,
02725 Solver::LocalSearchFilterBound filter_enum,
02726 Solver::LocalSearchOperation op_enum) {
02727 return RevAlloc(new TernaryObjectiveFilter(vars,
02728 secondary_vars,
02729 size,
02730 values,
02731 objective,
02732 filter_enum,
02733 OperationFromEnum(op_enum)));
02734 }
02735
02736
02737
02738 class FindOneNeighbor : public DecisionBuilder {
02739 public:
02740 FindOneNeighbor(Assignment* const assignment,
02741 SolutionPool* const pool,
02742 LocalSearchOperator* const ls_operator,
02743 DecisionBuilder* const sub_decision_builder,
02744 const SearchLimit* const limit,
02745 const std::vector<LocalSearchFilter*>& filters);
02746 virtual ~FindOneNeighbor() {}
02747 virtual Decision* Next(Solver* const solver);
02748 virtual string DebugString() const {
02749 return "FindOneNeighbor";
02750 }
02751
02752 private:
02753 bool FilterAccept(const Assignment* delta, const Assignment* deltadelta);
02754 void SynchronizeAll();
02755 void SynchronizeFilters(const Assignment* assignment);
02756
02757 Assignment* const assignment_;
02758 scoped_ptr<Assignment> reference_assignment_;
02759 SolutionPool* const pool_;
02760 LocalSearchOperator* const ls_operator_;
02761 DecisionBuilder* const sub_decision_builder_;
02762 SearchLimit* limit_;
02763 const SearchLimit* const original_limit_;
02764 bool neighbor_found_;
02765 std::vector<LocalSearchFilter*> filters_;
02766 };
02767
02768
02769
02770
02771 FindOneNeighbor::FindOneNeighbor(Assignment* const assignment,
02772 SolutionPool* const pool,
02773 LocalSearchOperator* const ls_operator,
02774 DecisionBuilder* const sub_decision_builder,
02775 const SearchLimit* const limit,
02776 const std::vector<LocalSearchFilter*>& filters)
02777 : assignment_(assignment),
02778 reference_assignment_(new Assignment(assignment_)),
02779 pool_(pool),
02780 ls_operator_(ls_operator),
02781 sub_decision_builder_(sub_decision_builder),
02782 limit_(NULL),
02783 original_limit_(limit),
02784 neighbor_found_(false),
02785 filters_(filters) {
02786 CHECK(NULL != assignment);
02787 CHECK(NULL != ls_operator);
02788
02789
02790 if (NULL == limit) {
02791 Solver* const solver = assignment_->solver();
02792 limit_ = solver->MakeLimit(kint64max, kint64max, kint64max, 1);
02793 } else {
02794 limit_ = limit->MakeClone();
02795 }
02796 }
02797
02798 Decision* FindOneNeighbor::Next(Solver* const solver) {
02799 CHECK(NULL != solver);
02800
02801 if (original_limit_ != NULL) {
02802 limit_->Copy(original_limit_);
02803 }
02804
02805 if (!neighbor_found_) {
02806
02807
02808
02809
02810
02811
02812 pool_->Initialize(assignment_);
02813 SynchronizeAll();
02814 }
02815
02816 {
02817
02818 Assignment* assignment_copy =
02819 solver->MakeAssignment(reference_assignment_.get());
02820 int counter = 0;
02821
02822 DecisionBuilder* restore =
02823 solver->MakeRestoreAssignment(assignment_copy);
02824 if (sub_decision_builder_) {
02825 restore = solver->Compose(restore, sub_decision_builder_);
02826 }
02827 Assignment* delta = solver->MakeAssignment();
02828 Assignment* deltadelta = solver->MakeAssignment();
02829 while (true) {
02830 delta->Clear();
02831 deltadelta->Clear();
02832 solver->TopPeriodicCheck();
02833 if (++counter >= FLAGS_cp_local_search_sync_frequency &&
02834 pool_->SyncNeeded(reference_assignment_.get())) {
02835
02836 counter = 0;
02837 SynchronizeAll();
02838 }
02839
02840 if (!limit_->Check()
02841 && ls_operator_->MakeNextNeighbor(delta, deltadelta)) {
02842 solver->neighbors_ += 1;
02843
02844
02845
02846
02847
02848 const bool mh_filter =
02849 AcceptDelta(solver->ParentSearch(), delta, deltadelta);
02850 const bool move_filter = FilterAccept(delta, deltadelta);
02851 if (mh_filter && move_filter) {
02852 solver->filtered_neighbors_ += 1;
02853 assignment_copy->Copy(reference_assignment_.get());
02854 assignment_copy->Copy(delta);
02855 if (solver->NestedSolve(restore, false)) {
02856 solver->accepted_neighbors_ += 1;
02857 assignment_->Store();
02858 neighbor_found_ = true;
02859 return NULL;
02860 }
02861 }
02862 } else {
02863 if (neighbor_found_) {
02864 AcceptNeighbor(solver->ParentSearch());
02865
02866
02867
02868 pool_->RegisterNewSolution(assignment_);
02869 SynchronizeAll();
02870 } else {
02871 break;
02872 }
02873 }
02874 }
02875 }
02876 solver->Fail();
02877 return NULL;
02878 }
02879
02880 bool FindOneNeighbor::FilterAccept(const Assignment* delta,
02881 const Assignment* deltadelta) {
02882 bool ok = true;
02883 for (int i = 0; i < filters_.size(); ++i) {
02884 if (filters_[i]->IsIncremental()) {
02885 ok = filters_[i]->Accept(delta, deltadelta) && ok;
02886 } else {
02887 ok = ok && filters_[i]->Accept(delta, deltadelta);
02888 }
02889 }
02890 return ok;
02891 }
02892
02893 void FindOneNeighbor::SynchronizeAll() {
02894 pool_->GetNextSolution(reference_assignment_.get());
02895 neighbor_found_ = false;
02896 limit_->Init();
02897 ls_operator_->Start(reference_assignment_.get());
02898 SynchronizeFilters(reference_assignment_.get());
02899 }
02900
02901 void FindOneNeighbor::SynchronizeFilters(const Assignment* assignment) {
02902 for (int i = 0; i < filters_.size(); ++i) {
02903 filters_[i]->Synchronize(assignment);
02904 }
02905 }
02906
02907
02908
02909 class LocalSearchPhaseParameters : public BaseObject {
02910 public:
02911 LocalSearchPhaseParameters(SolutionPool* const pool,
02912 LocalSearchOperator* ls_operator,
02913 DecisionBuilder* sub_decision_builder,
02914 SearchLimit* const limit,
02915 const std::vector<LocalSearchFilter*>& filters)
02916 : solution_pool_(pool),
02917 ls_operator_(ls_operator),
02918 sub_decision_builder_(sub_decision_builder),
02919 limit_(limit),
02920 filters_(filters) {}
02921 ~LocalSearchPhaseParameters() {}
02922 virtual string DebugString() const { return "LocalSearchPhaseParameters"; }
02923
02924 SolutionPool* solution_pool() const { return solution_pool_; }
02925 LocalSearchOperator* ls_operator() const { return ls_operator_; }
02926 DecisionBuilder* sub_decision_builder() const {
02927 return sub_decision_builder_;
02928 }
02929 SearchLimit* limit() const { return limit_; }
02930 const std::vector<LocalSearchFilter*>& filters() const { return filters_; }
02931
02932 private:
02933 SolutionPool* const solution_pool_;
02934 LocalSearchOperator* const ls_operator_;
02935 DecisionBuilder* const sub_decision_builder_;
02936 SearchLimit* const limit_;
02937 std::vector<LocalSearchFilter*> filters_;
02938 };
02939
02940 LocalSearchPhaseParameters* Solver::MakeLocalSearchPhaseParameters(
02941 LocalSearchOperator* const ls_operator,
02942 DecisionBuilder* const sub_decision_builder) {
02943 return MakeLocalSearchPhaseParameters(MakeDefaultSolutionPool(),
02944 ls_operator,
02945 sub_decision_builder,
02946 NULL,
02947 std::vector<LocalSearchFilter*>());
02948 }
02949
02950 LocalSearchPhaseParameters* Solver::MakeLocalSearchPhaseParameters(
02951 LocalSearchOperator* const ls_operator,
02952 DecisionBuilder* const sub_decision_builder,
02953 SearchLimit* const limit) {
02954 return MakeLocalSearchPhaseParameters(MakeDefaultSolutionPool(),
02955 ls_operator,
02956 sub_decision_builder,
02957 limit,
02958 std::vector<LocalSearchFilter*>());
02959 }
02960
02961 LocalSearchPhaseParameters* Solver::MakeLocalSearchPhaseParameters(
02962 LocalSearchOperator* const ls_operator,
02963 DecisionBuilder* const sub_decision_builder,
02964 SearchLimit* const limit,
02965 const std::vector<LocalSearchFilter*>& filters) {
02966 return MakeLocalSearchPhaseParameters(MakeDefaultSolutionPool(),
02967 ls_operator,
02968 sub_decision_builder,
02969 limit,
02970 filters);
02971 }
02972
02973 LocalSearchPhaseParameters* Solver::MakeLocalSearchPhaseParameters(
02974 SolutionPool* const pool,
02975 LocalSearchOperator* const ls_operator,
02976 DecisionBuilder* const sub_decision_builder) {
02977 return MakeLocalSearchPhaseParameters(pool,
02978 ls_operator,
02979 sub_decision_builder,
02980 NULL,
02981 std::vector<LocalSearchFilter*>());
02982 }
02983
02984 LocalSearchPhaseParameters* Solver::MakeLocalSearchPhaseParameters(
02985 SolutionPool* const pool,
02986 LocalSearchOperator* const ls_operator,
02987 DecisionBuilder* const sub_decision_builder,
02988 SearchLimit* const limit) {
02989 return MakeLocalSearchPhaseParameters(pool,
02990 ls_operator,
02991 sub_decision_builder,
02992 limit,
02993 std::vector<LocalSearchFilter*>());
02994 }
02995
02996 LocalSearchPhaseParameters* Solver::MakeLocalSearchPhaseParameters(
02997 SolutionPool* const pool,
02998 LocalSearchOperator* const ls_operator,
02999 DecisionBuilder* const sub_decision_builder,
03000 SearchLimit* const limit,
03001 const std::vector<LocalSearchFilter*>& filters) {
03002 return RevAlloc(new LocalSearchPhaseParameters(pool,
03003 ls_operator,
03004 sub_decision_builder,
03005 limit,
03006 filters));
03007 }
03008
03009 namespace {
03010
03011
03012
03013
03014
03015
03016
03017
03018
03019 class NestedSolveDecision : public Decision {
03020 public:
03021
03022 enum StateType {
03023 DECISION_PENDING,
03024 DECISION_FAILED,
03025 DECISION_FOUND
03026 };
03027
03028 NestedSolveDecision(DecisionBuilder* const db,
03029 bool restore,
03030 const std::vector<SearchMonitor*>& monitors);
03031 NestedSolveDecision(DecisionBuilder* const db,
03032 bool restore);
03033 virtual ~NestedSolveDecision() {}
03034 virtual void Apply(Solver* const solver);
03035 virtual void Refute(Solver* const solver);
03036 virtual string DebugString() const {
03037 return "NestedSolveDecision";
03038 }
03039 int state() const { return state_; }
03040
03041 private:
03042 DecisionBuilder* const db_;
03043 bool restore_;
03044 std::vector<SearchMonitor*> monitors_;
03045 int state_;
03046 };
03047
03048 NestedSolveDecision::NestedSolveDecision(DecisionBuilder* const db,
03049 bool restore,
03050 const std::vector<SearchMonitor*>& monitors)
03051 : db_(db),
03052 restore_(restore),
03053 monitors_(monitors),
03054 state_(DECISION_PENDING) {
03055 CHECK(NULL != db);
03056 }
03057
03058 NestedSolveDecision::NestedSolveDecision(DecisionBuilder* const db,
03059 bool restore)
03060 : db_(db), restore_(restore), state_(DECISION_PENDING) {
03061 CHECK(NULL != db);
03062 }
03063
03064 void NestedSolveDecision::Apply(Solver* const solver) {
03065 CHECK(NULL != solver);
03066 if (solver->NestedSolve(db_, restore_,
03067 monitors_.data(), monitors_.size())) {
03068 solver->SaveAndSetValue(&state_, static_cast<int>(DECISION_FOUND));
03069 } else {
03070 solver->SaveAndSetValue(&state_, static_cast<int>(DECISION_FAILED));
03071 }
03072 }
03073
03074 void NestedSolveDecision::Refute(Solver* const solver) {}
03075
03076
03077
03078
03079
03080
03081
03082
03083
03084
03085 class LocalSearch : public DecisionBuilder {
03086 public:
03087 LocalSearch(Assignment* const assignment,
03088 SolutionPool* const pool,
03089 LocalSearchOperator* const ls_operator,
03090 DecisionBuilder* const sub_decision_builder,
03091 SearchLimit* const limit,
03092 const std::vector<LocalSearchFilter*>& filters);
03093
03094
03095 LocalSearch(IntVar* const* vars,
03096 int size,
03097 SolutionPool* const pool,
03098 DecisionBuilder* const first_solution,
03099 LocalSearchOperator* const ls_operator,
03100 DecisionBuilder* const sub_decision_builder,
03101 SearchLimit* const limit,
03102 const std::vector<LocalSearchFilter*>& filters);
03103 virtual ~LocalSearch();
03104 virtual Decision* Next(Solver* const solver);
03105 virtual string DebugString() const {
03106 return "LocalSearch";
03107 }
03108 virtual void Accept(ModelVisitor* const visitor) const;
03109
03110 protected:
03111 void PushFirstSolutionDecision(DecisionBuilder* first_solution);
03112 void PushLocalSearchDecision();
03113
03114 private:
03115 Assignment* assignment_;
03116 SolutionPool* const pool_;
03117 LocalSearchOperator* const ls_operator_;
03118 DecisionBuilder* const sub_decision_builder_;
03119 std::vector<NestedSolveDecision*> nested_decisions_;
03120 int nested_decision_index_;
03121 SearchLimit* const limit_;
03122 const std::vector<LocalSearchFilter*> filters_;
03123 bool has_started_;
03124 };
03125
03126 LocalSearch::LocalSearch(Assignment* const assignment,
03127 SolutionPool* const pool,
03128 LocalSearchOperator* const ls_operator,
03129 DecisionBuilder* const sub_decision_builder,
03130 SearchLimit* const limit,
03131 const std::vector<LocalSearchFilter*>& filters)
03132 : assignment_(assignment),
03133 pool_(pool),
03134 ls_operator_(ls_operator),
03135 sub_decision_builder_(sub_decision_builder),
03136 nested_decision_index_(0),
03137 limit_(limit),
03138 filters_(filters),
03139 has_started_(false) {
03140 CHECK(NULL != assignment);
03141 CHECK(NULL != ls_operator);
03142 Solver* const solver = assignment_->solver();
03143 DecisionBuilder* restore = solver->MakeRestoreAssignment(assignment_);
03144 PushFirstSolutionDecision(restore);
03145 PushLocalSearchDecision();
03146 }
03147
03148 LocalSearch::LocalSearch(IntVar* const* vars,
03149 int size,
03150 SolutionPool* const pool,
03151 DecisionBuilder* const first_solution,
03152 LocalSearchOperator* const ls_operator,
03153 DecisionBuilder* const sub_decision_builder,
03154 SearchLimit* const limit,
03155 const std::vector<LocalSearchFilter*>& filters)
03156 : assignment_(NULL),
03157 pool_(pool),
03158 ls_operator_(ls_operator),
03159 sub_decision_builder_(sub_decision_builder),
03160 nested_decision_index_(0),
03161 limit_(limit),
03162 filters_(filters),
03163 has_started_(false) {
03164 CHECK(NULL != first_solution);
03165 CHECK(NULL != ls_operator);
03166 CHECK_GE(size, 1);
03167 Solver* const solver = vars[0]->solver();
03168 assignment_ = solver->MakeAssignment();
03169 assignment_->Add(vars, size);
03170 PushFirstSolutionDecision(first_solution);
03171 PushLocalSearchDecision();
03172 }
03173
03174 LocalSearch::~LocalSearch() {}
03175
03176
03177 void LocalSearch::Accept(ModelVisitor* const visitor) const {
03178 DCHECK(assignment_ != NULL);
03179 visitor->BeginVisitExtension(ModelVisitor::kVariableGroupExtension);
03180
03181 const std::vector<IntVarElement>& elements =
03182 assignment_->IntVarContainer().elements();
03183 if (!elements.empty()) {
03184 std::vector<IntVar*> vars;
03185 for (ConstIter<std::vector<IntVarElement> > it(elements); !it.at_end(); ++it) {
03186 vars.push_back((*it).Var());
03187 }
03188 visitor->VisitIntegerVariableArrayArgument(ModelVisitor::kVarsArgument,
03189 vars.data(),
03190 vars.size());
03191 }
03192 const std::vector<IntervalVarElement>& interval_elements =
03193 assignment_->IntervalVarContainer().elements();
03194 if (!interval_elements.empty()) {
03195 std::vector<IntervalVar*> interval_vars;
03196 for (ConstIter<std::vector<IntervalVarElement> > it(interval_elements);
03197 !it.at_end();
03198 ++it) {
03199 interval_vars.push_back((*it).Var());
03200 }
03201 visitor->VisitIntervalArrayArgument(ModelVisitor::kIntervalsArgument,
03202 interval_vars.data(),
03203 interval_vars.size());
03204 }
03205 visitor->EndVisitExtension(ModelVisitor::kVariableGroupExtension);
03206 }
03207
03208
03209
03210
03211
03212
03213
03214 Decision* LocalSearch::Next(Solver* const solver) {
03215 CHECK(NULL != solver);
03216 CHECK_LT(0, nested_decisions_.size());
03217 if (!has_started_) {
03218 nested_decision_index_ = 0;
03219 solver->SaveAndSetValue(&has_started_, true);
03220 } else if (nested_decision_index_ < 0) {
03221 solver->Fail();
03222 }
03223 NestedSolveDecision* decision = nested_decisions_[nested_decision_index_];
03224 const int state = decision->state();
03225 switch (state) {
03226 case NestedSolveDecision::DECISION_FAILED: {
03227 if (!LocalOptimumReached(solver->ActiveSearch())) {
03228 nested_decision_index_ = -1;
03229 }
03230 solver->Fail();
03231 return NULL;
03232 }
03233 case NestedSolveDecision::DECISION_PENDING: {
03234
03235
03236 const int32 kLocalSearchBalancedTreeDepth = 32;
03237 const int depth = solver->SearchDepth();
03238 if (depth < kLocalSearchBalancedTreeDepth) {
03239 return solver->balancing_decision();
03240 } else if (depth > kLocalSearchBalancedTreeDepth) {
03241 solver->Fail();
03242 }
03243 return decision;
03244 }
03245 case NestedSolveDecision::DECISION_FOUND: {
03246
03247 if (nested_decision_index_ + 1 < nested_decisions_.size()) {
03248 ++nested_decision_index_;
03249 }
03250 return NULL;
03251 }
03252 default: {
03253 LOG(ERROR) << "Unknown local search state";
03254 return NULL;
03255 }
03256 }
03257 return NULL;
03258 }
03259
03260 void LocalSearch::PushFirstSolutionDecision(
03261 DecisionBuilder* first_solution) {
03262 CHECK(first_solution);
03263 Solver* const solver = assignment_->solver();
03264 DecisionBuilder* store = solver->MakeStoreAssignment(assignment_);
03265 DecisionBuilder* first_solution_and_store =
03266 solver->Compose(first_solution, sub_decision_builder_, store);
03267 std::vector<SearchMonitor*> monitor;
03268 monitor.push_back(limit_);
03269 nested_decisions_.push_back(
03270 solver->RevAlloc(new NestedSolveDecision(first_solution_and_store,
03271 false,
03272 monitor)));
03273 }
03274
03275 void LocalSearch::PushLocalSearchDecision() {
03276 Solver* const solver = assignment_->solver();
03277 DecisionBuilder* find_neighbors =
03278 solver->RevAlloc(new FindOneNeighbor(assignment_,
03279 pool_,
03280 ls_operator_,
03281 sub_decision_builder_,
03282 limit_,
03283 filters_));
03284 nested_decisions_.push_back(
03285 solver->RevAlloc(new NestedSolveDecision(find_neighbors, false)));
03286 }
03287
03288 class DefaultSolutionPool : public SolutionPool {
03289 public:
03290 DefaultSolutionPool() : reference_assignment_(NULL) {}
03291
03292 virtual ~DefaultSolutionPool() {}
03293
03294 virtual void Initialize(Assignment* const assignment) {
03295 reference_assignment_.reset(new Assignment(assignment));
03296 }
03297
03298 virtual void RegisterNewSolution(Assignment* const assignment) {
03299 reference_assignment_->Copy(assignment);
03300 }
03301
03302 virtual void GetNextSolution(Assignment* const assignment) {
03303 assignment->Copy(reference_assignment_.get());
03304 }
03305
03306 virtual bool SyncNeeded(Assignment* const local_assignment) {
03307 return false;
03308 }
03309 private:
03310 scoped_ptr<Assignment> reference_assignment_;
03311 };
03312 }
03313
03314 SolutionPool* Solver::MakeDefaultSolutionPool() {
03315 return RevAlloc(new DefaultSolutionPool());
03316 }
03317
03318 DecisionBuilder* Solver::MakeLocalSearchPhase(
03319 Assignment* assignment,
03320 LocalSearchPhaseParameters* parameters) {
03321 return RevAlloc(new LocalSearch(assignment,
03322 parameters->solution_pool(),
03323 parameters->ls_operator(),
03324 parameters->sub_decision_builder(),
03325 parameters->limit(),
03326 parameters->filters()));
03327 }
03328
03329 DecisionBuilder* Solver::MakeLocalSearchPhase(
03330 const std::vector<IntVar*>& vars,
03331 DecisionBuilder* first_solution,
03332 LocalSearchPhaseParameters* parameters) {
03333 return MakeLocalSearchPhase(vars.data(),
03334 vars.size(),
03335 first_solution,
03336 parameters);
03337 }
03338
03339 DecisionBuilder* Solver::MakeLocalSearchPhase(
03340 IntVar* const* vars, int size,
03341 DecisionBuilder* first_solution,
03342 LocalSearchPhaseParameters* parameters) {
03343 return RevAlloc(new LocalSearch(vars, size,
03344 parameters->solution_pool(),
03345 first_solution,
03346 parameters->ls_operator(),
03347 parameters->sub_decision_builder(),
03348 parameters->limit(),
03349 parameters->filters()));
03350 }
03351 }