Introduce MakeWeightedMinimize objective; deprecate MakeSearchLog(period, var) in favor of MakeSearchLog(period, OptimizeVar)
This commit is contained in:
@@ -812,7 +812,7 @@ class Solver {
|
||||
IntVar* MakeIsLessVar(IntExpr* const left, IntExpr* const right);
|
||||
// b == (left < right)
|
||||
Constraint* MakeIsLessCt(IntExpr* const left, IntExpr* const right,
|
||||
IntVar* const b);
|
||||
IntVar* const b);
|
||||
// left < right
|
||||
Constraint* MakeLess(IntVar* const left, IntVar* const right);
|
||||
// expr < value
|
||||
@@ -1077,7 +1077,7 @@ class Solver {
|
||||
//
|
||||
// This is very useful to implement propagators that may only modify
|
||||
// the start min or end min.
|
||||
IntervalVar* MakeIntervalRelaxedMax(IntervalVar* const interval_var);
|
||||
IntervalVar* MakeIntervalRelaxedMax(IntervalVar* const interval_var);
|
||||
|
||||
// ----- scheduling constraints -----
|
||||
|
||||
@@ -1198,6 +1198,23 @@ IntervalVar* MakeIntervalRelaxedMax(IntervalVar* const interval_var);
|
||||
// Create a objective with a given sense (true = maximization).
|
||||
OptimizeVar* MakeOptimize(bool maximize, IntVar* const v, int64 step);
|
||||
|
||||
// Create a minimization weighted objective. The actual objective is
|
||||
// scalar_prod(vars, weights).
|
||||
OptimizeVar* MakeWeightedMinimize(const vector<IntVar*>& vars,
|
||||
const vector<int64>& weights,
|
||||
int64 step);
|
||||
|
||||
// Create a maximization weigthed objective.
|
||||
OptimizeVar* MakeWeightedMaximize(const vector<IntVar*>& vars,
|
||||
const vector<int64>& weights,
|
||||
int64 step);
|
||||
|
||||
// Create a weighted objective with a given sense (true = maximization).
|
||||
OptimizeVar* MakeWeightedOptimize(bool maximize,
|
||||
const vector<IntVar*>& vars,
|
||||
const vector<int64>& weights,
|
||||
int64 step);
|
||||
|
||||
// ----- Meta-heuristics -----
|
||||
// Search monitors which try to get the search out of local optima.
|
||||
|
||||
@@ -1380,28 +1397,39 @@ IntervalVar* MakeIntervalRelaxedMax(IntervalVar* const interval_var);
|
||||
|
||||
#endif
|
||||
|
||||
// TODO(user): DEPRECATE API of MakeSearchLog(.., IntVar* var,..).
|
||||
// ----- Search Log -----
|
||||
// The SearchMonitors below will display a periodic search log
|
||||
// on LOG(INFO) every branch_count branches explored.
|
||||
|
||||
// Create a search monitor that will display a periodic search log
|
||||
// on LOG(INFO).
|
||||
SearchMonitor* MakeSearchLog(int period);
|
||||
SearchMonitor* MakeSearchLog(int branch_count);
|
||||
|
||||
// Create a search monitor that will display a periodic search log
|
||||
// on LOG(INFO). At each solution, this monitor will also display
|
||||
// the objective value.
|
||||
SearchMonitor* MakeSearchLog(int period, IntVar* const objective);
|
||||
// At each solution, this monitor also display the objective value.
|
||||
SearchMonitor* MakeSearchLog(int branch_count, IntVar* const objective);
|
||||
|
||||
// Create a search monitor that will call the display callback at each
|
||||
// solution.
|
||||
SearchMonitor* MakeSearchLog(int period,
|
||||
// At each solution, this monitor will also display result of @p
|
||||
// display_callback.
|
||||
SearchMonitor* MakeSearchLog(int branch_count,
|
||||
ResultCallback<string>* display_callback);
|
||||
|
||||
// Create a search monitor that will call the display callback and display
|
||||
// the objective value at each solution.
|
||||
SearchMonitor* MakeSearchLog(int period,
|
||||
// At each solution, this monitor will display the objective value and the
|
||||
// result of @p display_callback.
|
||||
SearchMonitor* MakeSearchLog(int branch_count,
|
||||
IntVar* objective,
|
||||
ResultCallback<string>* display_callback);
|
||||
|
||||
// OptimizeVar Search Logs
|
||||
// At each solution, this monitor will also display the objective->Print().
|
||||
|
||||
SearchMonitor* MakeSearchLog(int branch_count, OptimizeVar* const objective);
|
||||
|
||||
// Create a search monitor that will also print the result of the
|
||||
// display callback.
|
||||
SearchMonitor* MakeSearchLog(int branch_count,
|
||||
OptimizeVar* const objective,
|
||||
ResultCallback<string>* display_callback);
|
||||
|
||||
|
||||
// ----- Search Trace ------
|
||||
|
||||
// Create a search monitor that will trace precisely the behavior of the
|
||||
@@ -1588,10 +1616,10 @@ IntervalVar* MakeIntervalRelaxedMax(IntervalVar* const interval_var);
|
||||
// Returns a decision builder for which the left-most leaf corresponds
|
||||
// to assignment, the rest of the tree being explored using 'db'.
|
||||
DecisionBuilder* MakeDecisionBuilderFromAssignment(
|
||||
Assignment* const assignment,
|
||||
DecisionBuilder* const db,
|
||||
const IntVar* const* vars,
|
||||
int size);
|
||||
Assignment* const assignment,
|
||||
DecisionBuilder* const db,
|
||||
const IntVar* const* vars,
|
||||
int size);
|
||||
|
||||
// SolveOnce will collapse a search tree described by a 'db' decision
|
||||
// builder, and a set of monitors and wrap it into a single point.
|
||||
@@ -2587,6 +2615,9 @@ class SolutionCollector : public SearchMonitor {
|
||||
DISALLOW_COPY_AND_ASSIGN(SolutionCollector);
|
||||
};
|
||||
|
||||
// TODO(user): Refactor this into an Objective class:
|
||||
// - print methods for AtNode and AtSolution.
|
||||
// - support for weighted objective and lexicographical objective.
|
||||
|
||||
// ---------- Objective Management ----------
|
||||
|
||||
@@ -2601,15 +2632,15 @@ class OptimizeVar : public SearchMonitor {
|
||||
// Returns the best value found during search.
|
||||
int64 best() const { return best_; }
|
||||
|
||||
// Returns the variable passed in the ctor.
|
||||
// Returns the variable that is optimized.
|
||||
IntVar* Var() const { return var_; }
|
||||
|
||||
// Internal methods
|
||||
virtual void EnterSearch();
|
||||
virtual void RestartSearch();
|
||||
virtual void RefuteDecision(Decision* d);
|
||||
virtual bool AtSolution();
|
||||
virtual bool AcceptSolution();
|
||||
virtual string Print() const;
|
||||
virtual string DebugString() const;
|
||||
|
||||
void ApplyBound();
|
||||
@@ -2680,8 +2711,8 @@ class IntervalVar : public PropagationBaseObject {
|
||||
static const int64 kMaxValidValue;
|
||||
IntervalVar(Solver* const solver, const string& name)
|
||||
: PropagationBaseObject(solver),
|
||||
start_expr_(NULL), duration_expr_(NULL), end_expr_(NULL),
|
||||
performed_expr_(NULL) {
|
||||
start_expr_(NULL), duration_expr_(NULL), end_expr_(NULL),
|
||||
performed_expr_(NULL) {
|
||||
set_name(name);
|
||||
}
|
||||
virtual ~IntervalVar() {}
|
||||
|
||||
@@ -755,7 +755,9 @@ class SymmetryBreaker : public DecisionVisitor {
|
||||
|
||||
class SearchLog : public SearchMonitor {
|
||||
public:
|
||||
SearchLog(Solver* const s, IntVar* const obj,
|
||||
SearchLog(Solver* const s,
|
||||
OptimizeVar* const obj,
|
||||
IntVar* const var,
|
||||
ResultCallback<string>* display_callback,
|
||||
int period);
|
||||
virtual ~SearchLog();
|
||||
@@ -778,7 +780,8 @@ class SearchLog : public SearchMonitor {
|
||||
|
||||
const int period_;
|
||||
scoped_ptr<WallTimer> timer_;
|
||||
IntVar* const obj_;
|
||||
IntVar* const var_;
|
||||
OptimizeVar* const obj_;
|
||||
scoped_ptr<ResultCallback<string> > display_callback_;
|
||||
int nsol_;
|
||||
int64 tick_;
|
||||
|
||||
@@ -32,12 +32,15 @@ namespace operations_research {
|
||||
|
||||
// ---------- Search Log ---------
|
||||
|
||||
SearchLog::SearchLog(Solver* const s, IntVar* const obj,
|
||||
SearchLog::SearchLog(Solver* const s,
|
||||
OptimizeVar* const obj,
|
||||
IntVar* const var,
|
||||
ResultCallback<string>* display_callback,
|
||||
int period)
|
||||
: SearchMonitor(s),
|
||||
period_(period),
|
||||
timer_(new WallTimer),
|
||||
var_(var),
|
||||
obj_(obj),
|
||||
display_callback_(display_callback),
|
||||
nsol_(0),
|
||||
@@ -48,6 +51,7 @@ SearchLog::SearchLog(Solver* const s, IntVar* const obj,
|
||||
max_depth_(0),
|
||||
sliding_min_depth_(0),
|
||||
sliding_max_depth_(0) {
|
||||
CHECK(obj == NULL || var == NULL) << "Either var or obj need to be NULL.";
|
||||
if (display_callback_ != NULL) {
|
||||
display_callback_->CheckIsRepeatable();
|
||||
}
|
||||
@@ -81,9 +85,18 @@ bool SearchLog::AtSolution() {
|
||||
Maintain();
|
||||
const int depth = solver()->SearchDepth();
|
||||
string obj_str = "";
|
||||
int64 current = 0;
|
||||
bool objective_updated = false;
|
||||
if (obj_ != NULL) {
|
||||
const int64 current = obj_->Value();
|
||||
obj_str = StringPrintf("objective value = %" GG_LL_FORMAT "d, ", current);
|
||||
current = obj_->Var()->Value();
|
||||
obj_str = obj_->Print();
|
||||
objective_updated = true;
|
||||
} else if (var_!= NULL) {
|
||||
current = var_->Value();
|
||||
StringAppendF(&obj_str, "%" GG_LL_FORMAT "d", current);
|
||||
objective_updated = true;
|
||||
}
|
||||
if (objective_updated) {
|
||||
if (current >= objective_min_) {
|
||||
StringAppendF(&obj_str,
|
||||
"objective minimum = %" GG_LL_FORMAT "d, ",
|
||||
@@ -233,21 +246,30 @@ string SearchLog::MemoryUsage() {
|
||||
}
|
||||
|
||||
SearchMonitor* Solver::MakeSearchLog(int period) {
|
||||
return RevAlloc(new SearchLog(this, NULL, NULL, period));
|
||||
return RevAlloc(new SearchLog(this, NULL, NULL, NULL, period));
|
||||
}
|
||||
|
||||
SearchMonitor* Solver::MakeSearchLog(int period, IntVar* const obj) {
|
||||
return RevAlloc(new SearchLog(this, obj, NULL, period));
|
||||
SearchMonitor* Solver::MakeSearchLog(int period, IntVar* const var) {
|
||||
return RevAlloc(new SearchLog(this, NULL, var, NULL, period));
|
||||
}
|
||||
|
||||
SearchMonitor* Solver::MakeSearchLog(int period,
|
||||
ResultCallback<string>* display_callback) {
|
||||
return RevAlloc(new SearchLog(this, NULL, display_callback, period));
|
||||
return RevAlloc(new SearchLog(this, NULL, NULL, display_callback, period));
|
||||
}
|
||||
|
||||
SearchMonitor* Solver::MakeSearchLog(int period, IntVar* const obj,
|
||||
SearchMonitor* Solver::MakeSearchLog(int period, IntVar* const var,
|
||||
ResultCallback<string>* display_callback) {
|
||||
return RevAlloc(new SearchLog(this, obj, display_callback, period));
|
||||
return RevAlloc(new SearchLog(this, NULL, var, display_callback, period));
|
||||
}
|
||||
|
||||
SearchMonitor* Solver::MakeSearchLog(int period, OptimizeVar* const obj) {
|
||||
return RevAlloc(new SearchLog(this, obj, NULL, NULL, period));
|
||||
}
|
||||
|
||||
SearchMonitor* Solver::MakeSearchLog(int period, OptimizeVar* const obj,
|
||||
ResultCallback<string>* display_callback) {
|
||||
return RevAlloc(new SearchLog(this, obj, NULL, display_callback, period));
|
||||
}
|
||||
|
||||
// ---------- Search Trace ----------
|
||||
@@ -2148,6 +2170,10 @@ bool OptimizeVar::AtSolution() {
|
||||
return true;
|
||||
}
|
||||
|
||||
string OptimizeVar::Print() const {
|
||||
return StringPrintf("objective value = %" GG_LL_FORMAT "d, ", var_->Value());
|
||||
}
|
||||
|
||||
string OptimizeVar::DebugString() const {
|
||||
string out;
|
||||
if (maximize_) {
|
||||
@@ -2174,6 +2200,79 @@ OptimizeVar* Solver::MakeOptimize(bool maximize, IntVar* const v, int64 step) {
|
||||
return RevAlloc(new OptimizeVar(this, maximize, v, step));
|
||||
}
|
||||
|
||||
class WeightedOptimizeVar: public OptimizeVar {
|
||||
public:
|
||||
WeightedOptimizeVar(Solver* solver,
|
||||
bool maximize,
|
||||
const vector<IntVar*>& sub_objectives,
|
||||
const vector<int64>& weights,
|
||||
int64 step)
|
||||
: OptimizeVar(solver,
|
||||
maximize,
|
||||
solver->MakeScalProd(sub_objectives, weights)->Var(),
|
||||
step),
|
||||
size_(weights.size()) {
|
||||
CHECK_EQ(sub_objectives.size(), weights.size());
|
||||
sub_objectives_.reset(new IntVar*[size_]);
|
||||
memcpy(sub_objectives_.get(),
|
||||
sub_objectives.data(), size_ * sizeof(*sub_objectives.data()));
|
||||
weights_.reset(new int64[size_]);
|
||||
memcpy(weights_.get(),
|
||||
weights.data(), size_ * sizeof(*weights.data()));
|
||||
}
|
||||
|
||||
virtual ~WeightedOptimizeVar() {}
|
||||
virtual string Print() const;
|
||||
|
||||
private:
|
||||
const int64 size_;
|
||||
scoped_array<IntVar*> sub_objectives_;
|
||||
scoped_array<int64> weights_;
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(WeightedOptimizeVar);
|
||||
};
|
||||
|
||||
string WeightedOptimizeVar::Print() const {
|
||||
string result(OptimizeVar::Print());
|
||||
StringAppendF(&result, "\nWeighted Objective:\n");
|
||||
for (int i = 0; i < size_; ++i) {
|
||||
StringAppendF(&result, "Variable %s,\tvalue %lld,\tweight %lld\n",
|
||||
sub_objectives_[i]->name().c_str(),
|
||||
sub_objectives_[i]->Value(),
|
||||
weights_[i]);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
OptimizeVar* Solver::MakeWeightedOptimize(bool maximize,
|
||||
const vector<IntVar*>& sub_objectives,
|
||||
const vector<int64>& weights,
|
||||
int64 step) {
|
||||
return RevAlloc(new WeightedOptimizeVar(this,
|
||||
maximize,
|
||||
sub_objectives, weights,
|
||||
step));
|
||||
}
|
||||
|
||||
OptimizeVar* Solver::MakeWeightedMinimize(const vector<IntVar*>& sub_objectives,
|
||||
const vector<int64>& weights,
|
||||
int64 step) {
|
||||
return RevAlloc(new WeightedOptimizeVar(this,
|
||||
false,
|
||||
sub_objectives, weights,
|
||||
step));
|
||||
}
|
||||
|
||||
OptimizeVar* Solver::MakeWeightedMaximize(const vector<IntVar*>& sub_objectives,
|
||||
const vector<int64>& weights,
|
||||
int64 step) {
|
||||
return RevAlloc(new WeightedOptimizeVar(this,
|
||||
true,
|
||||
sub_objectives, weights,
|
||||
step));
|
||||
}
|
||||
|
||||
|
||||
// ---------- Metaheuristics ---------
|
||||
|
||||
class Metaheuristic : public SearchMonitor {
|
||||
|
||||
Reference in New Issue
Block a user