diff --git a/constraint_solver/constraint_solver.h b/constraint_solver/constraint_solver.h index 0440e0519e..ec892d6bdc 100644 --- a/constraint_solver/constraint_solver.h +++ b/constraint_solver/constraint_solver.h @@ -1759,6 +1759,14 @@ class Solver { LocalSearchOperator* RandomConcatenateOperators( const vector& ops); + // Create a local search operator that wraps another local search + // operator and limits the number of neighbors explored (i.e. calls + // to MakeNextNeighbor). When this limit is reached, + // MakeNextNeighbor() returns false. The counter is cleared when + // Start() is called. + LocalSearchOperator* MakeNeighborhoodLimit(LocalSearchOperator* const op, + int64 limit); + // Local Search decision builders factories. // Local search is used to improve a given solution. This initial solution // can be specified either by an Assignment or by a DecisionBulder, and the diff --git a/constraint_solver/local_search.cc b/constraint_solver/local_search.cc index a8ac9acae2..6d18fdc39c 100644 --- a/constraint_solver/local_search.cc +++ b/constraint_solver/local_search.cc @@ -1494,6 +1494,38 @@ void PathLNS::DeactivateUnactives() { } } +// ----- Limit the number of neighborhoods explored ----- + +class NeighborhoodLimit : public LocalSearchOperator { + public: + NeighborhoodLimit(LocalSearchOperator* const op, int64 limit) + : operator_(op), limit_(limit), run_(0) { + CHECK_NOTNULL(op); + CHECK_GT(limit, 0); + } + + virtual void Start(const Assignment* assignment) { + run_ = 0; + operator_->Start(assignment); + } + + virtual bool MakeNextNeighbor(Assignment* delta, Assignment* deltadelta) { + if (++run_ > limit_) { + return false; + } + return operator_->MakeNextNeighbor(delta, deltadelta); + } + private: + LocalSearchOperator* const operator_; + const int64 limit_; + int64 run_; +}; + +LocalSearchOperator* Solver::MakeNeighborhoodLimit( + LocalSearchOperator* const op, int64 limit) { + return RevAlloc(new NeighborhoodLimit(op, limit)); +} + // ----- Concatenation of operators ----- class CompoundOperator : public LocalSearchOperator {