non working versions of mtsearch_test
This commit is contained in:
204
examples/tests/mtsearch_test.cc
Normal file
204
examples/tests/mtsearch_test.cc
Normal file
@@ -0,0 +1,204 @@
|
||||
// Copyright 2009 Google Inc. All Rights Reserved.
|
||||
// Author: lperron@google.com (Laurent Perron)
|
||||
|
||||
#include <stddef.h>
|
||||
#include <vector>
|
||||
|
||||
#include "base/callback.h"
|
||||
#include "base/logging.h"
|
||||
#include "base/mutex.h"
|
||||
#include "base/scoped_ptr.h"
|
||||
#include "base/stringprintf.h"
|
||||
#include "base/synchronization.h"
|
||||
#include "constraint_solver/constraint_solver.h"
|
||||
#include "constraint_solver/constraint_solveri.h"
|
||||
|
||||
namespace operations_research {
|
||||
class UpVar : public BaseLNS {
|
||||
public:
|
||||
UpVar(const IntVar* const* vars, int size, int worker)
|
||||
: BaseLNS(vars, size), worker_(worker) {}
|
||||
|
||||
virtual ~UpVar() {}
|
||||
|
||||
virtual bool NextFragment(vector<int>* fragment) {
|
||||
bool all_done = true;
|
||||
for (int i = 0; i < Size(); ++i) {
|
||||
if (Value(i) == 0) {
|
||||
all_done = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (all_done) {
|
||||
VLOG(1) << "worker " << worker_ << " thinks search should terminate";
|
||||
return false;
|
||||
}
|
||||
fragment->push_back(worker_);
|
||||
return true;
|
||||
}
|
||||
private:
|
||||
const int worker_;
|
||||
};
|
||||
|
||||
void BuildModelWithSolution(int* const active,
|
||||
Mutex* const mutex,
|
||||
ParallelSolveSupport* const support,
|
||||
bool master,
|
||||
int worker) {
|
||||
Solver s(StringPrintf("Worker_%i", worker));
|
||||
IntVar* const x = s.MakeIntVar(0, 10, "x");
|
||||
IntVar* const y = s.MakeIntVar(0, 10, "y");
|
||||
Assignment* const solution = s.MakeAssignment();
|
||||
solution->Add(x);
|
||||
solution->Add(y);
|
||||
if (master) {
|
||||
solution->SetValue(x, 2);
|
||||
solution->SetValue(y, 4);
|
||||
support->RegisterInitialSolution(solution);
|
||||
ThreadSafeIncrement(active, mutex, 1);
|
||||
} else {
|
||||
CHECK(support->WaitForInitialSolution(solution, worker));
|
||||
CHECK_EQ(2, solution->Value(x));
|
||||
CHECK_EQ(4, solution->Value(y));
|
||||
ThreadSafeIncrement(active, mutex, 1);
|
||||
}
|
||||
}
|
||||
|
||||
void BuildModelWithoutSolution(int* const active,
|
||||
Mutex* const mutex,
|
||||
ParallelSolveSupport* const support,
|
||||
bool master,
|
||||
int worker) {
|
||||
Solver s(StringPrintf("Worker_%i", worker));
|
||||
if (master) {
|
||||
support->RegisterNoInitialSolution();
|
||||
ThreadSafeIncrement(active, mutex, 1);
|
||||
} else {
|
||||
Assignment* const solution = s.MakeAssignment();
|
||||
CHECK(!support->WaitForInitialSolution(solution, worker));
|
||||
ThreadSafeIncrement(active, mutex, 1);
|
||||
}
|
||||
}
|
||||
|
||||
void BuildModelWithSearch(int workers,
|
||||
ParallelSolveSupport* const support,
|
||||
bool master,
|
||||
int worker) {
|
||||
Solver s(StringPrintf("Worker_%i", worker));
|
||||
VLOG(1) << "Worker " << worker << " started";
|
||||
vector<IntVar*> vars;
|
||||
s.MakeBoolVarArray(workers, "vars", &vars);
|
||||
Assignment* const solution = s.MakeAssignment();
|
||||
solution->Add(vars);
|
||||
vector<int> coefficients;
|
||||
int obj_max = 0;
|
||||
for (int i = 0; i < workers; ++i) {
|
||||
const int value = (i + 1) * (i + 1);
|
||||
coefficients.push_back(value);
|
||||
obj_max += value;
|
||||
}
|
||||
IntVar* const objective = s.MakeScalProd(vars, coefficients)->Var();
|
||||
solution->AddObjective(objective);
|
||||
|
||||
SolutionCollector* const collector = master ?
|
||||
s.MakeLastSolutionCollector(solution) :
|
||||
NULL;
|
||||
|
||||
vector<SearchMonitor*> monitors;
|
||||
|
||||
if (master) {
|
||||
monitors.push_back(collector);
|
||||
|
||||
for (int i = 0; i < workers; ++i) {
|
||||
solution->SetValue(vars[i], 0);
|
||||
}
|
||||
solution->SetObjectiveValue(0);
|
||||
support->RegisterInitialSolution(solution);
|
||||
} else {
|
||||
CHECK(support->WaitForInitialSolution(solution, worker));
|
||||
CHECK_EQ(0, solution->ObjectiveValue());
|
||||
}
|
||||
|
||||
monitors.push_back(s.MakeMaximize(objective, 1));
|
||||
|
||||
UpVar* local_search_operator =
|
||||
s.RevAlloc(new UpVar(vars.data(), workers, worker));
|
||||
|
||||
DecisionBuilder* db = s.MakePhase(vars,
|
||||
Solver::CHOOSE_FIRST_UNBOUND,
|
||||
Solver::ASSIGN_MAX_VALUE);
|
||||
|
||||
SolutionPool* const pool = !master ?
|
||||
support->MakeSolutionPool(&s, worker) :
|
||||
s.MakeDefaultSolutionPool();
|
||||
|
||||
LocalSearchPhaseParameters* parameters =
|
||||
s.MakeLocalSearchPhaseParameters(pool, local_search_operator, db);
|
||||
|
||||
DecisionBuilder* const final_db = master ?
|
||||
support->MakeReplayDecisionBuilder(&s, solution) :
|
||||
s.MakeLocalSearchPhase(solution, parameters);
|
||||
|
||||
monitors.push_back(
|
||||
support->MakeCommunicationMonitor(&s, solution, master, worker));
|
||||
|
||||
s.Solve(final_db, monitors);
|
||||
if (master && collector->solution_count()) {
|
||||
CHECK_EQ(1, collector->solution_count());
|
||||
Assignment* const best_solution = collector->solution(0);
|
||||
CHECK_EQ(obj_max, best_solution->ObjectiveValue());
|
||||
}
|
||||
}
|
||||
|
||||
void TestInitialSolution() {
|
||||
LOG(INFO) << "TestInitialSolution";
|
||||
const int kWorkers = 4;
|
||||
int work_done = 0;
|
||||
Mutex mutex;
|
||||
scoped_ptr<ParallelSolveSupport> support(
|
||||
MakeMtSolveSupport(kWorkers,
|
||||
false,
|
||||
NewPermanentCallback(
|
||||
&BuildModelWithSolution,
|
||||
&work_done,
|
||||
&mutex)));
|
||||
|
||||
support->Run();
|
||||
CHECK_EQ(kWorkers + 1, work_done);
|
||||
}
|
||||
|
||||
void TestNoInitialSolution() {
|
||||
LOG(INFO) << "TestNoInitialSolution";
|
||||
const int kWorkers = 4;
|
||||
int work_done = 0;
|
||||
Mutex mutex;
|
||||
scoped_ptr<ParallelSolveSupport> support(
|
||||
MakeMtSolveSupport(kWorkers,
|
||||
false,
|
||||
NewPermanentCallback(
|
||||
&BuildModelWithoutSolution,
|
||||
&work_done,
|
||||
&mutex)));
|
||||
support->Run();
|
||||
CHECK_EQ(kWorkers + 1, work_done);
|
||||
}
|
||||
|
||||
void TestModelWithSearch() {
|
||||
LOG(INFO) << "TestModelWithSearch";
|
||||
const int kSlaves = 4;
|
||||
scoped_ptr<ParallelSolveSupport> support(
|
||||
MakeMtSolveSupport(kSlaves,
|
||||
true,
|
||||
NewPermanentCallback(
|
||||
&BuildModelWithSearch,
|
||||
kSlaves)));
|
||||
support->Run();
|
||||
}
|
||||
} // namespace operations_research
|
||||
|
||||
int main(int argc, char **argv) {
|
||||
operations_research::TestInitialSolution();
|
||||
operations_research::TestNoInitialSolution();
|
||||
operations_research::TestModelWithSearch();
|
||||
return 0;
|
||||
}
|
||||
@@ -628,6 +628,14 @@ $(OBJ_DIR)/tsp.$O: $(EX_DIR)/cpp/tsp.cc $(SRC_DIR)/constraint_solver/routing.h
|
||||
$(BIN_DIR)/tsp$E: $(ROUTING_DEPS) $(OBJ_DIR)/tsp.$O
|
||||
$(CCC) $(CFLAGS) $(OBJ_DIR)/tsp.$O $(ROUTING_LNK) $(LDFLAGS) $(EXEOUT)tsp$E
|
||||
|
||||
# CP tests.
|
||||
|
||||
$(OBJ_DIR)/mtsearch_test.$O:$(EX_DIR)/tests/mtsearch_test.cc $(SRC_DIR)/constraint_solver/constraint_solver.h
|
||||
$(CCC) $(CFLAGS) -c $(EX_DIR)$Stests/mtsearch_test.cc $(OBJ_OUT)mtsearch_test.$O
|
||||
|
||||
$(BIN_DIR)/mtsearch_test$E: $(CP_DEPS) $(OBJ_DIR)/mtsearch_test.$O
|
||||
$(CCC) $(CFLAGS) $(OBJ_DIR)/mtsearch_test.$O $(CP_LNK) $(LDFLAGS) $(EXEOUT)mtsearch_test$E
|
||||
|
||||
# Linear Programming Examples
|
||||
|
||||
$(OBJ_DIR)/strawberry_fields_with_column_generation.$O: $(EX_DIR)/cpp/strawberry_fields_with_column_generation.cc $(SRC_DIR)/linear_solver/linear_solver.h
|
||||
|
||||
@@ -42,5 +42,11 @@ class Barrier {
|
||||
int num_to_exit_;
|
||||
DISALLOW_COPY_AND_ASSIGN(Barrier);
|
||||
};
|
||||
|
||||
template<class T, class TT>
|
||||
inline T ThreadSafeIncrement( T* value, Mutex* sm, TT inc ) {
|
||||
MutexLock l(sm);
|
||||
return (*value) += inc;
|
||||
}
|
||||
} // namespace operations_research
|
||||
#endif // OR_TOOLS_BASE_SYNCHRONIZATION_H_
|
||||
|
||||
@@ -4967,8 +4967,9 @@ class SolutionPool : public BaseObject {
|
||||
|
||||
class ParallelSolveSupport {
|
||||
public:
|
||||
ParallelSolveSupport(bool maximize,
|
||||
Callback3<ParallelSolveSupport* const, bool, int>* run_model);
|
||||
typedef Callback3<ParallelSolveSupport*, bool, int> ModelBuilder;
|
||||
|
||||
ParallelSolveSupport(bool maximize, ModelBuilder* const run_model);
|
||||
|
||||
virtual ~ParallelSolveSupport();
|
||||
|
||||
@@ -5034,7 +5035,7 @@ class ParallelSolveSupport {
|
||||
// Are we maximizing.
|
||||
const bool maximize_;
|
||||
// Callback to run the model
|
||||
scoped_ptr<Callback3<ParallelSolveSupport* const, bool, int> > run_model_;
|
||||
scoped_ptr<ModelBuilder> run_model_;
|
||||
};
|
||||
|
||||
// This method creates an instance of ParallelSolveSupport suited for
|
||||
@@ -5045,7 +5046,7 @@ class ParallelSolveSupport {
|
||||
ParallelSolveSupport* MakeMtSolveSupport(
|
||||
int workers,
|
||||
bool maximize,
|
||||
Callback3<ParallelSolveSupport* const, bool, int>* run_model);
|
||||
ParallelSolveSupport::ModelBuilder* const model_builder);
|
||||
#endif
|
||||
} // namespace operations_research
|
||||
#endif // OR_TOOLS_CONSTRAINT_SOLVER_CONSTRAINT_SOLVER_H_
|
||||
|
||||
@@ -39,7 +39,7 @@ class MtSolveSupport : public ParallelSolveSupport {
|
||||
public:
|
||||
MtSolveSupport(int workers,
|
||||
bool maximize,
|
||||
Callback3<ParallelSolveSupport* const, bool, int>* run_model);
|
||||
ModelBuilder* const run_model);
|
||||
|
||||
virtual ~MtSolveSupport();
|
||||
|
||||
@@ -95,16 +95,16 @@ class MtSolveSupport : public ParallelSolveSupport {
|
||||
// Start master.
|
||||
pool.Add(NewCallback(
|
||||
run_model_.get(),
|
||||
&Callback3<ParallelSolveSupport* const, bool, int>::Run,
|
||||
reinterpret_cast<ParallelSolveSupport* const>(this),
|
||||
&ModelBuilder::Run,
|
||||
reinterpret_cast<ParallelSolveSupport*>(this),
|
||||
true,
|
||||
-1));
|
||||
|
||||
for (int index = 0; index < workers_; ++index) {
|
||||
pool.Add(NewCallback(
|
||||
run_model_.get(),
|
||||
&Callback3<ParallelSolveSupport* const, bool, int>::Run,
|
||||
reinterpret_cast<ParallelSolveSupport* const>(this),
|
||||
&ModelBuilder::Run,
|
||||
reinterpret_cast<ParallelSolveSupport*>(this),
|
||||
false,
|
||||
index));
|
||||
}
|
||||
@@ -268,7 +268,7 @@ class MtSolutionDispatcher : public SearchMonitor {
|
||||
|
||||
ParallelSolveSupport::ParallelSolveSupport(
|
||||
bool maximize,
|
||||
Callback3<ParallelSolveSupport* const, bool, int>* run_model)
|
||||
ModelBuilder* const run_model)
|
||||
: local_solution_(new AssignmentProto()),
|
||||
maximize_(maximize),
|
||||
run_model_(run_model) {
|
||||
@@ -284,7 +284,7 @@ ParallelSolveSupport::~ParallelSolveSupport() {}
|
||||
MtSolveSupport::MtSolveSupport(
|
||||
int workers,
|
||||
bool maximize,
|
||||
Callback3<ParallelSolveSupport* const, bool, int>* run_model)
|
||||
ParallelSolveSupport::ModelBuilder* const run_model)
|
||||
: ParallelSolveSupport(maximize, run_model),
|
||||
workers_(workers),
|
||||
best_exported_cost_(maximize_ ? kint64min : kint64max),
|
||||
@@ -301,8 +301,8 @@ MtSolveSupport::MtSolveSupport(
|
||||
ParallelSolveSupport* MakeMtSolveSupport(
|
||||
int workers,
|
||||
bool maximize,
|
||||
Callback3<ParallelSolveSupport* const, bool, int>* run_model) {
|
||||
return new MtSolveSupport(workers, maximize, run_model);
|
||||
ParallelSolveSupport::ModelBuilder* const model_builder) {
|
||||
return new MtSolveSupport(workers, maximize, model_builder);
|
||||
}
|
||||
|
||||
MtSolveSupport::~MtSolveSupport() {}
|
||||
|
||||
Reference in New Issue
Block a user