changed protected -> private in local search virtual methods; improved implementation of increasing element

This commit is contained in:
lperron@google.com
2011-05-09 08:30:19 +00:00
parent a35bd7b60e
commit 52f02233b4
6 changed files with 141 additions and 159 deletions

View File

@@ -58,9 +58,10 @@
#ifndef CONSTRAINT_SOLVER_CONSTRAINT_SOLVER_H_
#define CONSTRAINT_SOLVER_CONSTRAINT_SOLVER_H_
#include <vector>
#include <iosfwd>
#include <string>
#include <utility>
#include <vector>
#include "base/callback.h"
#include "base/commandlineflags.h"
@@ -76,6 +77,11 @@
#include "base/random.h"
class File;
template <typename R, typename T1, typename T2> class ResultCallback2;
template <typename R, typename T1> class ResultCallback1;
template <typename T1> class Callback1;
template <typename T> class ResultCallback;
using operations_research::WallTimer;
#define ClockTimer WallTimer
@@ -99,13 +105,13 @@ class DomainIntVar;
class EqualityVarCstCache;
class ExpressionCache;
class GreaterEqualCstCache;
class IntervalVar;
class IntervalVarAssignmentProto;
class IntervalVarElement;
class IntExpr;
class IntVar;
class IntVarAssignmentProto;
class IntVarElement;
class IntervalVar;
class IntervalVarAssignmentProto;
class IntervalVarElement;
class LessEqualCstCache;
class LocalSearchFilter;
class LocalSearchOperator;
@@ -124,10 +130,10 @@ class SolutionCollector;
class SolutionPool;
class Solver;
class SymmetryBreaker;
struct StateInfo;
struct Trail;
class UnequalityVarCstCache;
class VariableQueueCleaner;
struct StateInfo;
struct Trail;
template <class T> class SimpleRevFIFO;
// This enum is used internally to tag states in the search tree.
@@ -709,7 +715,9 @@ class Solver {
// Function based element. The constraint takes ownership of
// callback. The callback must be monotonic. It must be able to
// cope with any possible value in the domain of 'index'
// (potentially negative ones too).
// (potentially negative ones too). Furtermore, monotonicity is not
// checked. Thus giving a non monotonic function, or specifying an
// incorrect increasing parameter will result in undefined behavior.
IntExpr* MakeMonotonicElement(IndexEvaluator1* values,
bool increasing,
IntVar* const index);
@@ -3545,7 +3553,7 @@ class Pack : public Constraint {
class SolutionPool : public BaseObject {
public:
SolutionPool() {}
~SolutionPool() {}
virtual ~SolutionPool() {}
// This method is called to initialize the solution pool with the assignment
// from the local search.

View File

@@ -431,10 +431,6 @@ class IntVarLocalSearchOperator : public LocalSearchOperator {
IntVar* Var(int64 index) const { return vars_[index]; }
virtual bool SkipUnchanged(int index) const { return false; }
protected:
// Called by Start() after synchronizing the operator with the current
// assignment. Should be overridden instead of Start() to avoid calling
// IntVarLocalSearchOperator::Start explicitly.
virtual void OnStart() {}
int64 OldValue(int64 index) const { return old_values_[index]; }
void SetValue(int64 index, int64 value);
bool Activated(int64 index) const;
@@ -444,6 +440,10 @@ class IntVarLocalSearchOperator : public LocalSearchOperator {
void RevertChanges(bool incremental);
void AddVars(const IntVar* const* vars, int size);
private:
// Called by Start() after synchronizing the operator with the current
// assignment. Should be overridden instead of Start() to avoid calling
// IntVarLocalSearchOperator::Start explicitly.
virtual void OnStart() {}
void MarkChange(int64 index);
scoped_array<IntVar*> vars_;
@@ -496,7 +496,7 @@ class BaseLNS : public IntVarLocalSearchOperator {
virtual bool MakeNextNeighbor(Assignment* delta, Assignment* deltadelta);
virtual void InitFragments();
virtual bool NextFragment(vector<int>* fragment) = 0;
protected:
private:
// This method should not be overridden. Override InitFragments() instead.
virtual void OnStart();
};
@@ -514,9 +514,9 @@ class ChangeValue : public IntVarLocalSearchOperator {
virtual ~ChangeValue();
virtual bool MakeNextNeighbor(Assignment* delta, Assignment* deltadelta);
virtual int64 ModifyValue(int64 index, int64 value) = 0;
protected:
virtual void OnStart();
private:
virtual void OnStart();
int index_;
};
@@ -565,11 +565,6 @@ class PathOperator : public IntVarLocalSearchOperator {
// Number of next variables.
int number_of_nexts() const { return number_of_nexts_; }
protected:
virtual void OnStart();
// Called by OnStart() after initializing node information. Should be
// overriden instead of OnStart() to avoid calling PathOperator::OnStart
// explicitly.
virtual void OnNodeInitialization() {}
// Returns the index of the variable corresponding to the ith base node.
int64 BaseNode(int i) const { return base_nodes_[i]; }
int64 StartNode(int i) const { return path_starts_[base_paths_[i]]; }
@@ -620,10 +615,16 @@ class PathOperator : public IntVarLocalSearchOperator {
void ResetPosition() {
just_started_ = true;
}
protected:
const int number_of_nexts_;
const bool ignore_path_vars_;
private:
virtual void OnStart();
// Called by OnStart() after initializing node information. Should be
// overriden instead of OnStart() to avoid calling PathOperator::OnStart
// explicitly.
virtual void OnNodeInitialization() {}
bool CheckEnds() const;
bool IncrementPosition();
void InitializePathStarts();
@@ -668,13 +669,12 @@ class IntVarLocalSearchFilter : public LocalSearchFilter {
public:
IntVarLocalSearchFilter(const IntVar* const* vars, int size);
~IntVarLocalSearchFilter();
protected:
// Add variables to "track" to the filter.
void AddVars(const IntVar* const* vars, int size);
// This method should not be overridden. Override OnSynchronize() instead
// which is called before exiting this method.
virtual void Synchronize(const Assignment* assignment);
virtual void OnSynchronize() {}
protected:
// Add variables to "track" to the filter.
void AddVars(const IntVar* const* vars, int size);
bool FindIndex(const IntVar* const var, int64* index) const {
DCHECK(index != NULL);
return FindCopy(var_to_index_, var, index);
@@ -683,6 +683,8 @@ class IntVarLocalSearchFilter : public LocalSearchFilter {
IntVar* Var(int index) const { return vars_[index]; }
int64 Value(int index) const { return values_[index]; }
private:
virtual void OnSynchronize() {}
scoped_array<IntVar*> vars_;
scoped_array<int64> values_;
int size_;

View File

@@ -533,17 +533,13 @@ IntExprFunctionElement::~IntExprFunctionElement() {
// ----- Increasing Element -----
class MonotonicIntExprFunctionElement : public BaseIntExpr {
class IncreasingIntExprFunctionElement : public BaseIntExpr {
public:
MonotonicIntExprFunctionElement(Solver* const s,
IncreasingIntExprFunctionElement(Solver* const s,
ResultCallback1<int64, int64>* values,
bool increasing,
bool to_delete,
IntVar* const index)
: BaseIntExpr(s),
values_(values),
increasing_(increasing),
delete_(to_delete),
index_(index) {
DCHECK(values);
DCHECK(index);
@@ -551,124 +547,75 @@ class MonotonicIntExprFunctionElement : public BaseIntExpr {
values->CheckIsRepeatable();
}
virtual ~MonotonicIntExprFunctionElement() {
if (delete_) {
delete values_;
}
virtual ~IncreasingIntExprFunctionElement() {
delete values_;
}
virtual int64 Min() const {
return increasing_?
values_->Run(index_->Min()):
values_->Run(index_->Max());
return values_->Run(index_->Min());
}
virtual void SetMin(int64 m) {
const int64 expression_min = index_->Min();
const int64 expression_max = index_->Max();
if (increasing_) {
if (m > values_->Run(expression_max)) {
solver()->Fail();
}
int64 nmin = expression_min;
while (nmin <= expression_max && values_->Run(nmin) < m) {
nmin++;
}
DCHECK_LE(nmin, expression_max);
index_->SetMin(nmin);
} else {
if (m > values_->Run(expression_min)) {
solver()->Fail();
}
int64 nmax = expression_max;
while (nmax >= expression_min && values_->Run(nmax) < m) {
nmax--;
}
DCHECK_GE(nmax, expression_min);
index_->SetMax(nmax);
if (m > values_->Run(expression_max)) {
solver()->Fail();
}
int64 nmin = expression_min;
while (nmin <= expression_max && values_->Run(nmin) < m) {
nmin++;
}
DCHECK_LE(nmin, expression_max);
index_->SetMin(nmin);
}
virtual int64 Max() const {
return increasing_?
values_->Run(index_->Max()):
values_->Run(index_->Min());
return values_->Run(index_->Max());
}
virtual void SetMax(int64 m) {
const int64 expression_min = index_->Min();
const int64 expression_max = index_->Max();
if (increasing_) {
if (m < values_->Run(expression_min)) {
solver()->Fail();
}
int64 nmax = expression_max;
while (nmax >= expression_min && values_->Run(nmax) > m) {
nmax--;
}
DCHECK_GE(nmax, expression_min);
index_->SetMax(nmax);
} else {
if (m < values_->Run(expression_max)) {
solver()->Fail();
}
int64 nmin = expression_min;
while (nmin <= expression_max && values_->Run(nmin) > m) {
nmin++;
}
DCHECK_LE(nmin, expression_max);
index_->SetMin(nmin);
if (m < values_->Run(expression_min)) {
solver()->Fail();
}
int64 nmax = expression_max;
while (nmax >= expression_min && values_->Run(nmax) > m) {
nmax--;
}
DCHECK_GE(nmax, expression_min);
index_->SetMax(nmax);
}
virtual void SetRange(int64 mi, int64 ma) {
const int64 expression_min = index_->Min();
const int64 expression_max = index_->Max();
if (increasing_) {
if (mi > ma ||
ma < values_->Run(expression_min) ||
mi > values_->Run(expression_max)) {
solver()->Fail();
}
int64 nmax = expression_max;
while (nmax >= expression_min && values_->Run(nmax) > ma) {
nmax--;
}
DCHECK_GE(nmax, expression_min);
int64 nmin = expression_min;
while (nmin <= nmax && values_->Run(nmin) < mi) {
nmin++;
}
DCHECK_LE(nmin, nmax);
index_->SetRange(nmin, nmax);
} else {
if (mi > ma ||
ma < values_->Run(expression_max) ||
mi > values_->Run(expression_min)) {
solver()->Fail();
}
int64 nmin = expression_min;
while (nmin <= expression_max && values_->Run(nmin) > ma) {
nmin++;
}
DCHECK_LE(nmin, expression_max);
int64 nmax = expression_max;
while (nmax >= expression_min && values_->Run(nmax) < mi) {
nmax--;
}
DCHECK_GE(nmax, nmin);
index_->SetRange(nmin, nmax);
if (mi > ma ||
ma < values_->Run(expression_min) ||
mi > values_->Run(expression_max)) {
solver()->Fail();
}
int64 nmax = expression_max;
while (nmax >= expression_min && values_->Run(nmax) > ma) {
nmax--;
}
DCHECK_GE(nmax, expression_min);
int64 nmin = expression_min;
while (nmin <= nmax && values_->Run(nmin) < mi) {
nmin++;
}
DCHECK_LE(nmin, nmax);
index_->SetRange(nmin, nmax);
}
virtual string name() const {
return StringPrintf("MonotonicIntExprFunctionElement(values, %d, %s)",
increasing_, index_->name().c_str());
return StringPrintf("IncreasingIntExprFunctionElement(values, %s)",
index_->name().c_str());
}
virtual string DebugString() const {
return StringPrintf("MonotonicIntExprFunctionElement(values, %d, %s)",
increasing_, index_->DebugString().c_str());
return StringPrintf("IncreasingIntExprFunctionElement(values, %s)",
index_->DebugString().c_str());
}
virtual void WhenRange(Demon* d) {
@@ -676,8 +623,6 @@ class MonotonicIntExprFunctionElement : public BaseIntExpr {
}
private:
ResultCallback1<int64, int64>* values_;
const bool increasing_;
const bool delete_;
IntVar* const index_;
};
@@ -687,15 +632,39 @@ IntExpr* Solver::MakeElement(ResultCallback1<int64, int64>* values,
return RevAlloc(new IntExprFunctionElement(this, values, index, true));
}
namespace {
class OppositeCallback : public BaseObject {
public:
OppositeCallback(ResultCallback1<int64, int64>* const values)
: values_(values) {
CHECK_NOTNULL(values_);
values_->CheckIsRepeatable();
}
virtual ~OppositeCallback() {}
int64 Run(int64 index) {
return -values_->Run(index);
}
public:
scoped_ptr<ResultCallback1<int64, int64> > values_;
};
} // namespace
IntExpr* Solver::MakeMonotonicElement(ResultCallback1<int64, int64>* values,
bool increasing,
IntVar* const index) {
CHECK_EQ(this, index->solver());
return RevAlloc(new MonotonicIntExprFunctionElement(this,
values,
increasing,
true,
index));
if (increasing) {
return RevAlloc(new IncreasingIntExprFunctionElement(this, values, index));
} else {
OppositeCallback* const opposite_callback =
RevAlloc(new OppositeCallback(values));
ResultCallback1<int64, int64>* opposite_values =
NewPermanentCallback(opposite_callback, &OppositeCallback::Run);
return MakeOpposite(RevAlloc(
new IncreasingIntExprFunctionElement(this, opposite_values, index)));
}
}
// ----- IntIntExprFunctionElement -----

View File

@@ -321,22 +321,6 @@ class MoveTowardTargetLS: public IntVarLocalSearchOperator {
}
virtual ~MoveTowardTargetLS() {}
virtual void OnStart() {
// Do not change the value of variable_index_: this way, we keep going from
// where we last modified something. This is because we expect that most
// often, the variables we have just checked are less likely to be able
// to be changed to their target values than the ones we have not yet
// checked.
//
// Consider the case where oddly indexed variables can be assigned to their
// target values (no matter in what order they are considered), while even
// indexed ones cannot. Restarting at index 0 each time an odd-indexed
// variable is modified will cause a total of Theta(n^2) neighbors to be
// generated, while not restarting will produce only Theta(n) neighbors.
CHECK_GE(variable_index_, 0);
CHECK_LT(variable_index_, Size());
num_var_since_last_start_ = 0;
}
// Make a neighbor assigning one variable to its target value.
virtual bool MakeNextNeighbor(Assignment* delta, Assignment* deltadelta) {
@@ -358,6 +342,23 @@ class MoveTowardTargetLS: public IntVarLocalSearchOperator {
}
private:
virtual void OnStart() {
// Do not change the value of variable_index_: this way, we keep going from
// where we last modified something. This is because we expect that most
// often, the variables we have just checked are less likely to be able
// to be changed to their target values than the ones we have not yet
// checked.
//
// Consider the case where oddly indexed variables can be assigned to their
// target values (no matter in what order they are considered), while even
// indexed ones cannot. Restarting at index 0 each time an odd-indexed
// variable is modified will cause a total of Theta(n^2) neighbors to be
// generated, while not restarting will produce only Theta(n) neighbors.
CHECK_GE(variable_index_, 0);
CHECK_LT(variable_index_, Size());
num_var_since_last_start_ = 0;
}
// Target values
const vector<int64> target_;
@@ -699,9 +700,9 @@ class TwoOpt : public PathOperator {
virtual ~TwoOpt() {}
virtual bool MakeNeighbor();
virtual bool IsIncremental() const { return true; }
protected:
virtual void OnNodeInitialization() { last_ = -1; }
private:
virtual void OnNodeInitialization() { last_ = -1; }
int64 last_base_;
int64 last_;
};
@@ -879,9 +880,9 @@ class MakeActiveOperator : public PathOperator {
virtual ~MakeActiveOperator() {}
virtual bool MakeNextNeighbor(Assignment* delta, Assignment* deltadelta);
virtual bool MakeNeighbor();
protected:
virtual void OnNodeInitialization();
private:
virtual void OnNodeInitialization();
int inactive_node_;
};
@@ -957,9 +958,9 @@ class SwapActiveOperator : public PathOperator {
virtual ~SwapActiveOperator() {}
virtual bool MakeNextNeighbor(Assignment* delta, Assignment* deltadelta);
virtual bool MakeNeighbor();
protected:
virtual void OnNodeInitialization();
private:
virtual void OnNodeInitialization();
int inactive_node_;
};
@@ -1018,9 +1019,9 @@ class ExtendedSwapActiveOperator : public PathOperator {
virtual ~ExtendedSwapActiveOperator() {}
virtual bool MakeNextNeighbor(Assignment* delta, Assignment* deltadelta);
virtual bool MakeNeighbor();
protected:
virtual void OnNodeInitialization();
private:
virtual void OnNodeInitialization();
int inactive_node_;
};
@@ -1394,9 +1395,9 @@ class LinKernighan : public PathOperator {
bool topt);
virtual ~LinKernighan();
virtual bool MakeNeighbor();
protected:
virtual void OnNodeInitialization();
private:
virtual void OnNodeInitialization();
static const int kNeighbors;
bool InFromOut(int64 in_i, int64 in_j, int64* out, int64* gain);
@@ -2143,7 +2144,6 @@ class ObjectiveFilter : public IntVarLocalSearchFilter {
LSOperation* op);
virtual ~ObjectiveFilter();
virtual bool Accept(const Assignment* delta, const Assignment* deltadelta);
virtual void OnSynchronize();
virtual int64 SynchronizedElementValue(int64 index) = 0;
virtual bool EvaluateElementValue(const Assignment::IntContainer& container,
int index,
@@ -2151,11 +2151,6 @@ class ObjectiveFilter : public IntVarLocalSearchFilter {
int64* obj_value) = 0;
virtual bool IsIncremental() const { return true; }
protected:
int64 Evaluate(const Assignment* delta,
int64 current_value,
const int64* const out_values,
bool cache_delta_values);
const int primary_vars_size_;
int64* const cache_;
int64* const delta_cache_;
@@ -2165,6 +2160,12 @@ class ObjectiveFilter : public IntVarLocalSearchFilter {
int64 old_value_;
int64 old_delta_value_;
bool incremental_;
private:
virtual void OnSynchronize();
int64 Evaluate(const Assignment* delta,
int64 current_value,
const int64* const out_values,
bool cache_delta_values);
};
ObjectiveFilter::ObjectiveFilter(const IntVar* const* vars,

View File

@@ -26,7 +26,9 @@
#ifndef CONSTRAINT_SOLVER_ROUTING_H_
#define CONSTRAINT_SOLVER_ROUTING_H_
#include <stddef.h>
#include <string>
#include <utility>
#include <vector>
#include "base/commandlineflags.h"

View File

@@ -97,7 +97,7 @@ bool SearchLog::AtSolution() {
objective_updated = true;
} else if (var_!= NULL) {
current = var_->Value();
StringAppendF(&obj_str, "%" GG_LL_FORMAT "d", current);
StringAppendF(&obj_str, "%" GG_LL_FORMAT "d, ", current);
objective_updated = true;
}
if (objective_updated) {