Files
ortools-clone/documentation/tutorials/cplusplus/chap6/dummy_ls.cc
nikolaj.van.omme@gmail.com cc5b6c233f Doc automatic update
2014-12-19 20:57:44 +00:00

152 lines
4.9 KiB
C++

// Copyright 2011-2014 Google
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
//
// Dummy Local Search to understand the behavior of LSN Operators.
#include "constraint_solver/constraint_solveri.h"
#include "constraint_solver/constraint_solver.h"
DEFINE_int64(n, 4, "Size of the problem");
DEFINE_bool(initial_phase, true, "Do we use an initial phase to produce"
"the initial solution?");
DEFINE_int64(ls_time_limit, 10000, "LS time limit (in ms)");
DEFINE_int64(ls_branches_limit, 10000, "LS branches limit");
DEFINE_int64(ls_failures_limit, 10000, "LS failures limit");
DEFINE_int64(ls_solutions_limit, 1, "LS solutions limit");
DEFINE_bool(print_intermediate_solutions, true,
"Add a search log for the objective?");
namespace operations_research {
class DecreaseOneVar: public IntVarLocalSearchOperator {
public:
explicit DecreaseOneVar(const std::vector<IntVar*>& variables)
: IntVarLocalSearchOperator(variables),
variable_index_(0) {
VLOG(2) << "Creation of DecreaseOneVar Local Search Operator";
}
virtual ~DecreaseOneVar() {
VLOG(2) << "Destruction of DecreaseOneVar Local Search Operator";
}
protected:
// Make a neighbor assigning one variable to its target value.
virtual bool MakeOneNeighbor() {
if (variable_index_ == Size()) {
VLOG(1) << "End of neighborhood search";
return false;
}
const int64 current_value = Value(variable_index_);
SetValue(variable_index_, current_value - 1);
VLOG(1) << "Current value of variable index = "
<< variable_index_
<< " set to "
<< current_value - 1;
variable_index_ = variable_index_ + 1;
return true;
}
private:
virtual void OnStart() {
VLOG(1) << "Start new neighborhood search";
variable_index_ = 0;
}
int64 variable_index_;
};
void DummyLS(const int64 n, const bool init_phase) {
CHECK_GE(n, 2) << "size of problem (n) must be greater or equal than 2";
LOG(INFO) << "Dummy Local Search "
<< (init_phase ? "with initial phase" : "with initial solution");
Solver s("Dummy LS");
vector<IntVar*> vars;
s.MakeIntVarArray(n, 0, n-1, &vars);
IntVar* const sum_var = s.MakeSum(vars)->Var();
OptimizeVar* const obj = s.MakeMinimize(sum_var, 1);
// unique constraint x_0 >= 1
s.AddConstraint(s.MakeGreaterOrEqual(vars[0], 1));
// initial phase builder
DecisionBuilder * db = NULL;
// initial solution
Assignment * const initial_solution = s.MakeAssignment();
if (init_phase) {
db =
s.MakePhase(vars,
Solver::CHOOSE_FIRST_UNBOUND,
Solver::ASSIGN_MAX_VALUE);
} else {
initial_solution->Add(vars);
for (int i = 0; i < n; ++i) {
if (i % 2 == 0) {
initial_solution->SetValue(vars[i], n - 1);
} else {
initial_solution->SetValue(vars[i], n - 2);
}
}
}
// IntVarLocalSearchOperator
DecreaseOneVar one_var_ls(vars);
LocalSearchPhaseParameters* ls_params = NULL;
SearchLimit * const limit = s.MakeLimit(FLAGS_ls_time_limit,
FLAGS_ls_branches_limit,
FLAGS_ls_failures_limit,
FLAGS_ls_solutions_limit);
DecisionBuilder* ls = NULL;
if (init_phase) {
ls_params = s.MakeLocalSearchPhaseParameters(&one_var_ls, db, limit);
ls = s.MakeLocalSearchPhase(vars, db, ls_params);
} else {
ls_params = s.MakeLocalSearchPhaseParameters(&one_var_ls, NULL, limit);
ls = s.MakeLocalSearchPhase(initial_solution, ls_params);
}
SolutionCollector* const collector = s.MakeLastSolutionCollector();
collector->Add(vars);
collector->AddObjective(sum_var);
SearchMonitor* log = NULL;
if (FLAGS_print_intermediate_solutions) {
log = s.MakeSearchLog(1000, obj);
}
if (s.Solve(ls, collector, obj, log)) {
LOG(INFO) << "Objective value = " << collector->objective_value(0);
} else {
LG << "No solution...";
}
}
} // namespace operations_research
int main(int argc, char** argv) {
google::ParseCommandLineFlags(&argc, &argv, true);
operations_research::DummyLS(FLAGS_n, FLAGS_initial_phase);
return 0;
}