diff --git a/Makefile.build.cpp b/Makefile.build.cpp index ee406219a6..eda031c870 100644 --- a/Makefile.build.cpp +++ b/Makefile.build.cpp @@ -102,6 +102,7 @@ CONSTRAINT_SOLVER_LIB_OS = \ objs/expr_array.$O\ objs/expr_cst.$O\ objs/expressions.$O\ + objs/hybrid.$O\ objs/interval.$O\ objs/local_search.$O\ objs/nogoods.$O\ @@ -168,6 +169,9 @@ objs/expr_cst.$O:constraint_solver/expr_cst.cc objs/expressions.$O:constraint_solver/expressions.cc $(CCC) $(CFLAGS) -c constraint_solver/expressions.cc $(OBJOUT)objs/expressions.$O +objs/hybrid.$O:constraint_solver/hybrid.cc + $(CCC) $(CFLAGS) -c constraint_solver/hybrid.cc $(OBJOUT)objs/hybrid.$O + objs/interval.$O:constraint_solver/interval.cc $(CCC) $(CFLAGS) -c constraint_solver/interval.cc $(OBJOUT)objs/interval.$O diff --git a/constraint_solver/constraint_solver.h b/constraint_solver/constraint_solver.h index 2ae07feca5..cf2a0dede6 100644 --- a/constraint_solver/constraint_solver.h +++ b/constraint_solver/constraint_solver.h @@ -1640,6 +1640,12 @@ class Solver { SymmetryBreaker* const v3, SymmetryBreaker* const v4); + // ----- Simplex Connection ----- + + SearchMonitor* MakeSimplexConnection(Callback1* const builder, + Callback1* const modifier, + Callback1* const runner, + int simplex_frequency); // ----- Search Decicions and Decision Builders ----- diff --git a/constraint_solver/hybrid.cc b/constraint_solver/hybrid.cc new file mode 100644 index 0000000000..eba47b1536 --- /dev/null +++ b/constraint_solver/hybrid.cc @@ -0,0 +1,110 @@ +// Copyright 2010-2011 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. + +#include "base/callback.h" +#include "base/commandlineflags.h" +#include "base/integral_types.h" +#include "base/macros.h" +#include "base/scoped_ptr.h" +#include "constraint_solver/constraint_solver.h" +#include "linear_solver/linear_solver.h" + +DEFINE_int32(simplex_cleanup_frequency, 0, + "frequency to cleanup the simplex after each call, 0: no cleanup"); +DEFINE_bool(verbose_simplex_call, false, + "Do not suppress output of the simplex"); +DEFINE_bool(use_clp, true, "use Clp instead of glpk"); + +namespace operations_research { +class SimplexConstraint : public SearchMonitor { + public: + SimplexConstraint(Solver* const solver, + Callback1* const builder, + Callback1* const modifier, + Callback1* const runner, + int simplex_frequency) + : SearchMonitor(solver), + builder_(builder), + modifier_(modifier), + runner_(runner), + mp_solver_("InSearchSimplex", + (FLAGS_use_clp ? + MPSolver::CLP_LINEAR_PROGRAMMING : + MPSolver::GLPK_LINEAR_PROGRAMMING)), + counter_(0LL), + simplex_frequency_(simplex_frequency) { + if (builder != NULL) { + builder->CheckIsRepeatable(); + } + if (modifier != NULL) { + modifier->CheckIsRepeatable(); + } + if (runner != NULL) { + runner->CheckIsRepeatable(); + } + if (!FLAGS_verbose_simplex_call) { + mp_solver_.SuppressOutput(); + } + } + + virtual void EndInitialPropagation() { + mp_solver_.Clear(); + mp_solver_.Init(); + if (builder_.get() != NULL) { + builder_->Run(&mp_solver_); + } + RunOptim(); + } + + virtual void BeginNextDecision(DecisionBuilder* const b) { + if (++counter_ % simplex_frequency_ == 0) { + const int cleanup = FLAGS_simplex_cleanup_frequency * simplex_frequency_; + if (FLAGS_simplex_cleanup_frequency != 0 && counter_ % cleanup == 0) { + mp_solver_.Clear(); + mp_solver_.Init(); + if (builder_.get() != NULL) { + builder_->Run(&mp_solver_); + } + } + RunOptim(); + } + } + + void RunOptim() { + if (modifier_.get() != NULL) { + modifier_->Run(&mp_solver_); + } + if (runner_.get() != NULL) { + runner_->Run(&mp_solver_); + } + } + private: + scoped_ptr > builder_; + scoped_ptr > modifier_; + scoped_ptr > runner_; + MPSolver mp_solver_; + int64 counter_; + const int simplex_frequency_; + DISALLOW_COPY_AND_ASSIGN(SimplexConstraint); +}; + +SearchMonitor* Solver::MakeSimplexConnection( + Callback1* const builder, + Callback1* const modifier, + Callback1* const runner, + int frequency) { + return RevAlloc(new SimplexConstraint(this, builder, modifier, + runner, frequency)); +} + +} // namespace operations_research