Commit 01434b75 authored by Dmitry Bagaev's avatar Dmitry Bagaev
Browse files

WIP: update

parent 6b3cbdf8
......@@ -64,7 +64,7 @@ int main(int argc, char **argv) {
std::cout << " " << *it << std::endl;
}
std::cout << " Available optimizers:" << std::endl;
std::vector<std::string> availableOptimizers = TTSP::OptimizerInterface::getAvailableOptimizers();
std::vector<std::string> availableOptimizers = TTSP::OptimizerInterface::GetAvailableOptimizers();
for (auto it = availableOptimizers.begin(); it != availableOptimizers.end(); ++it) {
std::cout << " " << *it << std::endl;
}
......@@ -175,15 +175,17 @@ int main(int argc, char **argv) {
TTSP::OptimizerProperties properties;
properties["tau:use_closest"] = "false";
properties["tau:use_closest"] = "false";
properties["tau:strict_bound"] = "false";
TTSP::OptimizationParametersSpace space(solverName, "test", parameters);
TTSP::OptimizerInterface *optimizer = TTSP::OptimizerInterface::getOptimizer(optimizerType, space, properties, 10);
TTSP::OptimizerInterface *optimizer = TTSP::OptimizerInterface::GetOptimizer(optimizerType, space, properties, 10);
if (optimizer == nullptr) {
if (rank == 0) {
std::cout << "Optimizer " << optimizerType << " not found" << std::endl;
std::cout << " Available optimizers:" << std::endl;
std::vector<std::string> availableOptimizers = TTSP::OptimizerInterface::getAvailableOptimizers();
std::vector<std::string> availableOptimizers = TTSP::OptimizerInterface::GetAvailableOptimizers();
for (auto it = availableOptimizers.begin(); it != availableOptimizers.end(); ++it) {
std::cout << " " << *it << std::endl;
}
......@@ -205,7 +207,8 @@ int main(int argc, char **argv) {
matrix.GetInterval(mbeg, mend);
x.SetInterval(mbeg, mend);
for (int k = mbeg; k < mend; ++k) {
for (int k = mbeg;
k < mend; ++k) {
x[k] = 0.0;
}
......@@ -218,13 +221,95 @@ int main(int argc, char **argv) {
matrix.Load(next.first);
// if (rank == 0) std::cout << "Solving with A = " << next.first << " and b = " << next.second << std::endl;
auto invoke = [&solver, &matrix, &rhs, &x](const TTSP::OptimizationParameterPoints &before, const TTSP::OptimizationParameterPoints &after,
void *data) -> TTSP::OptimizationFunctionInvokeResult {
std::for_each(after.begin(), after.end(), [&solver](const TTSP::OptimizationParameterPoint &point) {
solver.SetParameter(point.first, INMOST::to_string(point.second));
});
INMOST::Sparse::Vector SOL("SOL", rhs.GetFirstIndex(), rhs.GetLastIndex());
std::fill(SOL.Begin(), SOL.End(), 0.0);
INMOST::MPIBarrier();
double tmp_time = Timer();
solver.SetMatrix(matrix);
bool is_solved = solver.Solve(rhs, SOL);
INMOST::MPIBarrier();
double time = Timer() - tmp_time;
std::for_each(before.begin(), before.end(), [&solver](const TTSP::OptimizationParameterPoint &point) {
solver.SetParameter(point.first, INMOST::to_string(point.second));
});
return std::make_pair(is_solved, time);
};
const TTSP::OptimizationParameterPoints &before = optimizer->GetSpace().GetPoints();
const TTSP::OptimizationParametersSuggestion &suggestion = optimizer->Suggest(invoke, nullptr);
const TTSP::OptimizationFunctionInvokeResult &result = invoke(before, suggestion.second, nullptr);
bool is_good = result.first;
double metrics = result.second;
optimizer->SaveResult(suggestion.first, before, suggestion.second, metrics, is_good);
if (is_good) {
optimizer->UpdateSpacePoints(suggestion.second);
}
TTSP::OptimizerVerbosityLevel verbosity = TTSP::OptimizerVerbosityLevel::Level3;
// On Level1 print some metadata information about solution and used parameters
if (rank == 0 && verbosity > TTSP::OptimizerVerbosityLevel::Level0) {
std::string metadata = solver.SolutionMetadataLine("\t");
std::for_each(suggestion.second.begin(), suggestion.second.end(), [&metadata](const TTSP::OptimizationParameterPoint &p) {
metadata += ("\t" + INMOST::to_string(p.second));
});
std::cout << metadata << std::endl;
}
// On Level2 also print information about next parameters
if (rank == 0 && verbosity > TTSP::OptimizerVerbosityLevel::Level1) {
std::cout << std::endl << "Next optimization parameters found for current iteration:" << std::endl;
const TTSP::OptimizationParameterPoints &points = optimizer->GetSpace().GetPoints();
std::for_each(points.begin(), points.end(), [](const TTSP::OptimizationParameterPoint &p) {
std::cout << "\t" << p.first << " = " << p.second << std::endl;
});
}
// On Level3 also print additional information about buffer
if (rank == 0 && verbosity > TTSP::OptimizerVerbosityLevel::Level2) {
std::cout << std::endl << "Optimization results buffer output:" << std::endl;
const TTSP::OptimizationParameterResultsBuffer &results = optimizer->GetResults();
optimizer->Solve(solver, matrix, rhs, x);
int index = 1;
std::for_each(results.begin(), results.end(), [&index](const TTSP::OptimizationParameterResult &result) {
std::cout << "\t" << index++ << "\t" << " [";
const TTSP::OptimizationParameterPoints &before = result.GetPointsBefore();
std::for_each(before.begin(), before.end(), [](const TTSP::OptimizationParameterPoint &point) {
std::cout << " " << point.first << "=" << point.second << " ";
});
std::cout << "] >> [";
const TTSP::OptimizationParameterPoints &after = result.GetPointsAfter();
std::for_each(after.begin(), after.end(), [](const TTSP::OptimizationParameterPoint &point) {
std::cout << " " << point.first << "=" << point.second << " ";
});
std::cout << "] " << result.GetMetrics() << std::endl;
});
}
if (rank == 0 && waitNext) {
std::cin.get();
}
INMOST::MPIBarrier();
}
}
......
......@@ -73,8 +73,9 @@ namespace TTSP {
});
}
OptimizationParameterPoints AlternatingOptimizer::MakeOptimizationIteration(INMOST::Solver &solver, INMOST::Sparse::Matrix &matrix,
INMOST::Sparse::Vector &RHS) {
OptimizationParametersSuggestion AlternatingOptimizer::Suggest(const std::function<OptimizationFunctionInvokeResult(const OptimizationParameterPoints &,
const OptimizationParameterPoints &,
void *)> &invoke, void *data) {
OptimizationParameterPoints points(space.GetParameters().size());
......@@ -97,7 +98,7 @@ namespace TTSP {
const OptimizationParameterResult &last = results.at(0);
const OptimizationParameterResult &before_last = results.at(1);
if (last.IsSolved() && (last.GetTime() < before_last.GetTime())) {
if (last.IsGood() && (last.GetMetrics() < before_last.GetMetrics())) {
current.UpdateIndex(current.NextIndex());
} else {
current.NextDirection();
......@@ -114,7 +115,7 @@ namespace TTSP {
});
}
return points;
return std::make_pair(handlers.at(current_handler_index).GetParameter(), points);
}
AlternatingOptimizer::~AlternatingOptimizer() {}
......
......@@ -19,10 +19,11 @@ namespace TTSP {
class AlternatingParameterHandler {
private:
const OptimizationParameter &parameter;
std::size_t direction;
std::size_t current_index;
std::size_t direction;
std::size_t current_index;
public:
explicit AlternatingParameterHandler(const OptimizationParameter &parameter);
AlternatingParameterHandler(const AlternatingParameterHandler &other);
const OptimizationParameter &GetParameter() const;
......@@ -40,13 +41,14 @@ namespace TTSP {
class AlternatingOptimizer : public OptimizerInterface {
private:
std::size_t current_handler_index;
std::size_t current_handler_index;
std::vector<AlternatingParameterHandler> handlers;
public:
AlternatingOptimizer(const OptimizationParametersSpace &space, const OptimizerProperties &properties, std::size_t buffer_capacity);
OptimizationParameterPoints MakeOptimizationIteration(INMOST::Solver &solver, INMOST::Sparse::Matrix &matrix,
INMOST::Sparse::Vector &RHS) override;
OptimizationParametersSuggestion Suggest(const std::function<OptimizationFunctionInvokeResult(const OptimizationParameterPoints &,
const OptimizationParameterPoints &,
void *)> &invoke, void *data) override;
virtual ~AlternatingOptimizer();
};
......@@ -54,5 +56,4 @@ namespace TTSP {
}
#endif //INMOST_TTSP_ALTERNATING_H
......@@ -217,8 +217,9 @@ namespace TTSP {
});
}
OptimizationParameterPoints AnnealingOptimizer::MakeOptimizationIteration(INMOST::Solver &solver, INMOST::Sparse::Matrix &matrix,
INMOST::Sparse::Vector &RHS) {
OptimizationParametersSuggestion AnnealingOptimizer::Suggest(const std::function<OptimizationFunctionInvokeResult(const OptimizationParameterPoints &,
const OptimizationParameterPoints &,
void *)> &invoke, void *data) {
OptimizationParameterPoints points(space.GetParameters().size());
......@@ -239,14 +240,14 @@ namespace TTSP {
const OptimizationParameterResult &before_last = results.at(1);
double temp = h.GetCurrentTemp();
double delta_e = last.GetTime() - before_last.GetTime();
double delta_e = last.GetMetrics() - before_last.GetMetrics();
double et = 1.0 / (1.0 + std::exp(delta_e / temp));
//double h = std::exp(-delta_e / temp);
double alpha = h.GetRandom();
if (last.IsSolved() && ((delta_e < 0.0) || alpha < et)) {
double update_value = last.GetPoints().at(current_handler_index).second;
if (last.IsGood() && ((delta_e < 0.0) || alpha < et)) {
double update_value = last.GetPointsAfter().at(current_handler_index).second;
h.SetValue(update_value);
}
......@@ -258,7 +259,7 @@ namespace TTSP {
});
}
return points;
return std::make_pair(handlers.at(current_handler_index).GetParameter(), points);
}
AnnealingOptimizer::~AnnealingOptimizer() {}
......
......@@ -88,8 +88,9 @@ namespace TTSP {
public:
AnnealingOptimizer(const OptimizationParametersSpace &space, const OptimizerProperties &properties, std::size_t buffer_capacity);
OptimizationParameterPoints MakeOptimizationIteration(INMOST::Solver &solver, INMOST::Sparse::Matrix &matrix,
INMOST::Sparse::Vector &RHS) override;
OptimizationParametersSuggestion Suggest(const std::function<OptimizationFunctionInvokeResult(const OptimizationParameterPoints &,
const OptimizationParameterPoints &,
void *)> &invoke, void *data) override;
virtual ~AnnealingOptimizer();
};
......
......@@ -10,52 +10,43 @@ namespace TTSP {
BruteforceOptimizer::BruteforceOptimizer(const OptimizationParametersSpace &space, const OptimizerProperties &properties, std::size_t buffer_capacity) :
OptimizerInterface(space, properties, buffer_capacity) {}
OptimizationParameterPoints BruteforceOptimizer::MakeOptimizationIteration(INMOST::Solver &solver, INMOST::Sparse::Matrix &matrix,
INMOST::Sparse::Vector &RHS) {
OptimizationParametersSuggestion BruteforceOptimizer::Suggest(const std::function<OptimizationFunctionInvokeResult(const OptimizationParameterPoints &,
const OptimizationParameterPoints &,
void *)> &invoke, void *data) {
const OptimizationParameters &parameters = space.GetParameters();
const OptimizationParameters &parameters = space.GetParameters();
const OptimizationParameterPoints &before = space.GetPoints();
OptimizationParameterPoints output(parameters.size());
std::transform(parameters.begin(), parameters.end(), output.begin(), [&](const OptimizationParametersEntry &entry) {
const std::vector<double> &values = entry.first.GetValues();
double tmp_time = 0.0;
double best_time = -1.0;
double best_value = 0.0;
double best_metrics = -1.0;
double best_value = 0.0;
std::for_each(values.begin(), values.end(), [&](double value) {
std::cout << "[TTSP] [Bruteforce] Solving with " << entry.first.GetName() << " = " << value << "\t\t";
solver.SetParameter(entry.first.GetName(), INMOST::to_string(value));
const OptimizationParameterPoints &after = space.GetPointsWithChangedParameter(entry.first, value);
INMOST::Sparse::Vector SOL("SOL", RHS.GetFirstIndex(), RHS.GetLastIndex());
std::fill(SOL.Begin(), SOL.End(), 0.0);
OptimizationFunctionInvokeResult result = invoke(before, after, data);
INMOST::MPIBarrier();
bool is_solved = result.first;
double metrics = result.second;
tmp_time = Timer();
solver.SetMatrix(matrix);
bool is_solved = solver.Solve(RHS, SOL);
INMOST::MPIBarrier();
double time = Timer() - tmp_time;
if (is_solved && (best_time < 0 || time < best_time)) {
best_time = time;
best_value = value;
if (is_solved && (best_metrics < 0 || metrics < best_metrics)) {
best_metrics = metrics;
best_value = value;
}
std::cout << "| Time = " << time << "\t" << is_solved << std::endl;
std::cout << "| Metrics = " << metrics << "\t" << is_solved << std::endl;
});
solver.SetParameter(entry.first.GetName(), INMOST::to_string(best_value));
return std::make_pair(entry.first.GetName(), best_value);
});
return output;
return std::make_pair(parameters.at(0).first, output);
}
BruteforceOptimizer::~BruteforceOptimizer() {}
......
......@@ -13,8 +13,9 @@ namespace TTSP {
public:
BruteforceOptimizer(const OptimizationParametersSpace &space, const OptimizerProperties &properties, std::size_t buffer_capacity);
OptimizationParameterPoints MakeOptimizationIteration(INMOST::Solver &solver, INMOST::Sparse::Matrix &matrix,
INMOST::Sparse::Vector &RHS) override;
OptimizationParametersSuggestion Suggest(const std::function<OptimizationFunctionInvokeResult(const OptimizationParameterPoints &,
const OptimizationParameterPoints &,
void *)> &invoke, void *data) override;
virtual ~BruteforceOptimizer();
};
......
......@@ -9,8 +9,9 @@ namespace TTSP {
NoopOptimizer::NoopOptimizer(const OptimizationParametersSpace &space, const OptimizerProperties &properties, std::size_t buffer_capacity) :
OptimizerInterface(space, properties, buffer_capacity) {}
OptimizationParameterPoints NoopOptimizer::MakeOptimizationIteration(INMOST::Solver &solver, INMOST::Sparse::Matrix &matrix,
INMOST::Sparse::Vector &RHS) {
OptimizationParametersSuggestion NoopOptimizer::Suggest(const std::function<OptimizationFunctionInvokeResult(const OptimizationParameterPoints &,
const OptimizationParameterPoints &,
void *)> &invoke, void *data) {
const OptimizationParameters &parameters = space.GetParameters();
OptimizationParameterPoints output(parameters.size());
......@@ -19,7 +20,7 @@ namespace TTSP {
return std::make_pair(entry.first.GetName(), entry.first.GetDefaultValue());
});
return output;
return std::make_pair(parameters.at(0).first, output);
}
NoopOptimizer::~NoopOptimizer() {}
......
......@@ -13,8 +13,9 @@ namespace TTSP {
public:
NoopOptimizer(const OptimizationParametersSpace &space, const OptimizerProperties &properties, std::size_t buffer_capacity);
OptimizationParameterPoints MakeOptimizationIteration(INMOST::Solver &solver, INMOST::Sparse::Matrix &matrix,
INMOST::Sparse::Vector &RHS) override;
OptimizationParametersSuggestion Suggest(const std::function<OptimizationFunctionInvokeResult(const OptimizationParameterPoints &,
const OptimizationParameterPoints &,
void *)> &invoke, void *data) override;
virtual ~NoopOptimizer();
};
......
......@@ -48,33 +48,33 @@ namespace TTSP {
}
const std::string &OptimizationParameter::GetName() const {
const std::string &OptimizationParameter::GetName() const noexcept {
return name;
}
const std::vector<double> &OptimizationParameter::GetValues() const {
const std::vector<double> &OptimizationParameter::GetValues() const noexcept {
return values;
}
double OptimizationParameter::GetMinimalValue() const {
double OptimizationParameter::GetMinimalValue() const noexcept {
return values.at(0);
}
double OptimizationParameter::GetMaximumValue() const {
double OptimizationParameter::GetMaximumValue() const noexcept {
return values.at(values.size() - 1);
}
double OptimizationParameter::GetClosestTo(double to) const {
double OptimizationParameter::GetClosestTo(double to) const noexcept {
return *std::min_element(values.begin(), values.end(), [to](double x, double y) {
return std::abs(x - to) < std::abs(y - to);
});
}
const std::size_t OptimizationParameter::GetValuesCount() const {
std::size_t OptimizationParameter::GetValuesCount() const noexcept {
return values.size();
}
const double &OptimizationParameter::GetDefaultValue() const {
double OptimizationParameter::GetDefaultValue() const noexcept {
return default_value;
}
......@@ -102,27 +102,27 @@ namespace TTSP {
return *this;
}
bool OptimizationParametersSpace::isSolverNameMatch(const std::string &solver_name) const {
bool OptimizationParametersSpace::isSolverNameMatch(const std::string &solver_name) const noexcept {
return this->solver_name == solver_name;
}
bool OptimizationParametersSpace::isSolverPrefixMatch(const std::string &solver_prefix) const {
bool OptimizationParametersSpace::isSolverPrefixMatch(const std::string &solver_prefix) const noexcept {
return this->solver_prefix == solver_prefix;
}
const std::string &OptimizationParametersSpace::GetSolverName() const {
const std::string &OptimizationParametersSpace::GetSolverName() const noexcept {
return solver_name;
}
const std::string &OptimizationParametersSpace::GetSolverPrefix() const {
const std::string &OptimizationParametersSpace::GetSolverPrefix() const noexcept {
return solver_prefix;
}
const OptimizationParameters &OptimizationParametersSpace::GetParameters() const {
const OptimizationParameters &OptimizationParametersSpace::GetParameters() const noexcept {
return parameters;
}
const OptimizationParameterPoints OptimizationParametersSpace::GetPoints() const {
const OptimizationParameterPoints OptimizationParametersSpace::GetPoints() const noexcept {
OptimizationParameterPoints points(parameters.size());
std::transform(parameters.begin(), parameters.end(), points.begin(), [](const OptimizationParametersEntry &p) {
return std::make_pair(p.first.GetName(), p.second);
......@@ -130,6 +130,15 @@ namespace TTSP {
return points;
}
const OptimizationParameterPoints OptimizationParametersSpace::GetPointsWithChangedParameter(const OptimizationParameter &parameter,
double value) const noexcept {
OptimizationParameterPoints points(parameters.size());
std::transform(parameters.begin(), parameters.end(), points.begin(), [&parameter, value](const OptimizationParametersEntry &p) {
return p.first.GetName() == parameter.GetName() ? std::make_pair(p.first.GetName(), value) : std::make_pair(p.first.GetName(), p.second);
});
return points;
}
void OptimizationParametersSpace::Update(const OptimizationParameterPoints &update) {
for (int i = 0; i < update.size(); ++i) {
parameters[i].second = update[i].second;
......@@ -137,20 +146,21 @@ namespace TTSP {
}
void OptimizationParameterResult::swap(OptimizationParameterResult &left, OptimizationParameterResult &right) {
std::swap(left.points, right.points);
std::swap(left.preconditioner_time, right.preconditioner_time);
std::swap(left.solve_time, right.solve_time);
std::swap(left.is_solved, right.is_solved);
std::swap(left.before, right.before);
std::swap(left.after, right.after);
std::swap(left.metrics, right.metrics);
std::swap(left.is_good, right.is_good);
}
OptimizationParameterResult::OptimizationParameterResult(const OptimizationParameterPoints &points,
double preconditioner_time, double solve_time, bool is_solved) :
points(points), preconditioner_time(preconditioner_time), solve_time(solve_time), is_solved(is_solved) {}
OptimizationParameterResult::OptimizationParameterResult(const OptimizationParameter &changed, const OptimizationParameterPoints &before,
const OptimizationParameterPoints &after,
double metrics, bool is_good) :
changed(changed), before(before), after(after), metrics(metrics), is_good(is_good) {}
OptimizationParameterResult::OptimizationParameterResult(const OptimizationParameterResult &other) :
points(other.points), preconditioner_time(other.preconditioner_time), solve_time(other.solve_time), is_solved(other.is_solved) {}
changed(other.changed), before(other.before), after(other.after), metrics(other.metrics), is_good(other.is_good) {}
OptimizationParameterResult::OptimizationParameterResult(OptimizationParameterResult &&other) noexcept {
OptimizationParameterResult::OptimizationParameterResult(OptimizationParameterResult &&other) noexcept : changed(std::move(other).changed) {
OptimizationParameterResult::swap(*this, other);
}
......@@ -160,25 +170,22 @@ namespace TTSP {
return *this;
}
const OptimizationParameterPoints &OptimizationParameterResult::GetPoints() const {
return points;
const OptimizationParameterPoints &OptimizationParameterResult::GetPointsBefore() const noexcept {
return before;
}
const double &OptimizationParameterResult::GetPreconditionerTime() const {
return preconditioner_time;
const OptimizationParameterPoints &OptimizationParameterResult::GetPointsAfter() const noexcept {
return after;
}
const double &OptimizationParameterResult::GetSolveTime() const {
return solve_time;
double OptimizationParameterResult::GetMetrics() const noexcept {
return metrics;
}
double OptimizationParameterResult::GetTime() const {
return preconditioner_time + solve_time;
bool OptimizationParameterResult::IsGood() const noexcept {
return is_good;
}
bool OptimizationParameterResult::IsSolved() const {
return is_solved;
}
void OptimizationParameterResultsBuffer::swap(OptimizationParameterResultsBuffer &left,
OptimizationParameterResultsBuffer &right) {
......@@ -201,7 +208,7 @@ namespace TTSP {
return *this;
}
std::deque<OptimizationParameterResult>::const_reverse_iterator OptimizationParameterResultsBuffer::begin() const {
std::deque<OptimizationParameterResult>::const_reverse_iterator OptimizationParameterResultsBuffer::begin() const noexcept {
return buffer.crbegin();
}
......@@ -209,7 +216,7 @@ namespace TTSP {
return *(begin() + index);
}
std::deque<OptimizationParameterResult>::const_reverse_iterator OptimizationParameterResultsBuffer::end() const {
std::deque<OptimizationParameterResult>::const_reverse_iterator OptimizationParameterResultsBuffer::end() const noexcept {
return buffer.crend();
}
......@@ -220,94 +227,56 @@ namespace TTSP {
buffer.push_back(result);
}
std::size_t OptimizationParameterResultsBuffer::size() const {
std::size_t OptimizationParameterResultsBuffer::size() const noexcept {
return buffer.size();
}
bool OptimizerInterface::Solve(INMOST::Solver &solver, INMOST::Sparse::Matrix &matrix, INMOST::Sparse::Vector &RHS, INMOST::Sparse::Vector &SOL,
GetPreconditionerTimeFromSolverLambda preconditioner_time, GetSolveTimeFromSolverLambda solve_time) {
int rank = INMOST::MPIGetRank();
const OptimizationParameterPoints &current = space.GetPoints();
std::for_each(current.begin(), current.end(), [&solver](const OptimizationParameterPoint &p) {
solver.SetParameter(p.first, INMOST::to_string(p.second));
});
solver.SetMatrix(matrix);
bool solved = solver.Solve(RHS, SOL);
SaveResult(current, solver, solved, preconditioner_time, solve_time);
const OptimizationParameterPoints &update = this->MakeOptimizationIteration(solver, matrix, RHS);
space.Update(update);
// On Level1 print some metadata information about solution and used parameters
if (rank == 0 && versbosity > OptimizerVerbosityLevel::Level0) {
std::string metadata = solver.SolutionMetadataLine("\t");
std::for_each(current.begin(), current.<