Commit 892ba96c authored by Dmitry Bagaev's avatar Dmitry Bagaev
Browse files

WIP: some improvments

parent 140a6240
......@@ -179,10 +179,9 @@ int main(int argc, char **argv) {
properties["tau:use_closest"] = "false";
properties["tau:strict_bound"] = "false";
TTSP::OptimizationParametersSpace space(solverName, "test", parameters);
TTSP::OptimizationParametersSpace space(solverName, "test", parameters, -1.0);
TTSP::OptimizerInterface *optimizer = TTSP::OptimizerInterface::GetOptimizer(optimizerType, space, properties, 10);
if (optimizer == nullptr) {
if (!TTSP::OptimizerInterface::IsOptimizerAvailable(optimizerType)) {
if (rank == 0) {
std::cout << "Optimizer " << optimizerType << " not found" << std::endl;
std::cout << " Available optimizers:" << std::endl;
......@@ -194,6 +193,8 @@ int main(int argc, char **argv) {
std::exit(0);
}
TTSP::OptimizerInterface *optimizer = TTSP::OptimizerInterface::GetOptimizer(optimizerType, space, properties, 50);
optimizer->SetVerbosityLevel(TTSP::OptimizerVerbosityLevel::Level1);
while (!series.end()) {
......@@ -255,11 +256,7 @@ int main(int argc, char **argv) {
bool is_good = result.first;
double metrics = result.second;
optimizer->SaveResult(suggestion.GetChangedParameter(), suggestion.GetPointsBefore(), suggestion.GetPointsAfter(), metrics, is_good);
if (is_good) {
optimizer->UpdateSpacePoints(suggestion.GetPointsAfter());
}
optimizer->SaveResult(suggestion.GetChangedParameter(), suggestion.GetPointsAfter(), metrics, is_good);
TTSP::OptimizerVerbosityLevel verbosity = TTSP::OptimizerVerbosityLevel::Level3;
......@@ -275,7 +272,7 @@ int main(int argc, char **argv) {
// 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->GetCurrentPoints();
const TTSP::OptimizationParameterPoints &points = optimizer->GetPoints();
std::for_each(points.begin(), points.end(), [](const TTSP::OptimizationParameterPoint &p) {
std::cout << "\t" << p.first << " = " << p.second << std::endl;
});
......
......@@ -24,7 +24,7 @@ namespace TTSP {
return current_index;
}
std::size_t AlternatingParameterHandler::NextIndex() {
std::size_t AlternatingParameterHandler::NextIndex() const {
std::size_t count = parameter.GetValues().size() - 1;
std::size_t index = current_index;
......@@ -75,57 +75,36 @@ namespace TTSP {
OptimizationParametersSuggestion AlternatingOptimizer::Suggest(const std::function<OptimizationFunctionInvokeResult(const OptimizationParameterPoints &,
const OptimizationParameterPoints &,
void *)> &invoke, void *data) {
void *)> &invoke, void *data) const {
OptimizationParameterPoints points(space.GetParameters().size());
if (results.size() < 2) {
if (results.size() == 0) {
std::transform(handlers.begin(), handlers.end(), points.begin(), [](const AlternatingParameterHandler &h) {
return std::make_pair(h.GetParameter().GetName(), h.GetParameter().GetValues().at(h.GetCurrentIndex()));
});
} else if (results.size() == 1) {
int i = 0;
std::transform(handlers.begin(), handlers.end(), points.begin(), [this, &i](AlternatingParameterHandler &h) {
return std::make_pair(
h.GetParameter().GetName(),
h.GetParameter().GetValues().at(i++ == current_handler_index ? h.NextIndex() : h.GetCurrentIndex())
);
});
}
} else {
AlternatingParameterHandler &current = handlers.at(current_handler_index);
const OptimizationParameterResult &last = results.at(0);
const OptimizationParameterResult &before_last = results.at(1);
if (last.IsGood() && (last.GetMetricsAfter() < before_last.GetMetricsAfter())) {
current.UpdateIndex(current.NextIndex());
} else {
current.NextDirection();
}
current_handler_index = (current_handler_index + 1) % (handlers.size());
int i = 0;
std::transform(handlers.begin(), handlers.end(), points.begin(), [this, &i](AlternatingParameterHandler &h) {
return std::make_pair(
h.GetParameter().GetName(),
h.GetParameter().GetValues().at(i++ == current_handler_index ? h.NextIndex() : h.GetCurrentIndex())
);
});
}
int i = 0;
std::transform(handlers.begin(), handlers.end(), points.begin(), [this, &i](const AlternatingParameterHandler &h) {
return std::make_pair(
h.GetParameter().GetName(),
h.GetParameter().GetValues().at(i++ == current_handler_index ? h.NextIndex() : h.GetCurrentIndex())
);
});
return OptimizationParametersSuggestion(handlers.at(current_handler_index).GetParameter(), GetCurrentPoints(), points);
return OptimizationParametersSuggestion(handlers.at(current_handler_index).GetParameter(), space.GetPoints(), space.GetMetrics(), points);
}
const OptimizationParameterPoints AlternatingOptimizer::GetCurrentPoints() const noexcept {
OptimizationParameterPoints points(space.GetParameters().size());
std::transform(handlers.cbegin(), handlers.cend(), points.begin(), [](const AlternatingParameterHandler &h) {
return std::make_pair(h.GetParameter().GetName(), h.GetParameter().GetValues().at(h.GetCurrentIndex()));
});
return points;
void AlternatingOptimizer::UpdateSpaceWithLatestResults() {
AlternatingParameterHandler &current = handlers.at(current_handler_index);
const OptimizationParameterResult &last = results.at(0);
if (last.IsGood() && (last.GetMetricsBefore() < 0.0 || last.GetMetricsAfter() < last.GetMetricsBefore())) {
current.UpdateIndex(current.NextIndex());
space.Update(current_handler_index, space.GetParameter(current_handler_index).GetValues().at(current.GetCurrentIndex()), last.GetMetricsAfter());
} else {
current.NextDirection();
}
current_handler_index = (current_handler_index + 1) % (handlers.size());
}
AlternatingOptimizer::~AlternatingOptimizer() {}
}
......@@ -19,8 +19,8 @@ namespace TTSP {
class AlternatingParameterHandler {
private:
const OptimizationParameter &parameter;
std::size_t direction;
std::size_t current_index;
mutable std::size_t direction;
public:
explicit AlternatingParameterHandler(const OptimizationParameter &parameter);
......@@ -32,7 +32,7 @@ namespace TTSP {
std::size_t GetCurrentIndex() const;
std::size_t NextIndex();
std::size_t NextIndex() const;
void NextDirection();
......@@ -43,14 +43,15 @@ namespace TTSP {
private:
std::size_t current_handler_index;
std::vector<AlternatingParameterHandler> handlers;
protected:
void UpdateSpaceWithLatestResults() override;
public:
AlternatingOptimizer(const OptimizationParametersSpace &space, const OptimizerProperties &properties, std::size_t buffer_capacity);
OptimizationParametersSuggestion Suggest(const std::function<OptimizationFunctionInvokeResult(const OptimizationParameterPoints &,
const OptimizationParameterPoints &,
void *)> &invoke, void *data) override;
const OptimizationParameterPoints GetCurrentPoints() const noexcept override;
void *)> &invoke, void *data) const override;
virtual ~AlternatingOptimizer();
};
......
......@@ -219,55 +219,34 @@ namespace TTSP {
OptimizationParametersSuggestion AnnealingOptimizer::Suggest(const std::function<OptimizationFunctionInvokeResult(const OptimizationParameterPoints &,
const OptimizationParameterPoints &,
void *)> &invoke, void *data) {
void *)> &invoke, void *data) const {
OptimizationParameterPoints points(space.GetParameters().size());
if (results.size() < 2) {
if (results.size() == 0) {
std::transform(handlers.begin(), handlers.end(), points.begin(), [](const AnnealingParameterHandler &h) {
return std::make_pair(h.GetParameter().GetName(), h.GetCurrentValue());
});
} else if (results.size() == 1) {
int i = 0;
std::transform(handlers.begin(), handlers.end(), points.begin(), [this, &i](const AnnealingParameterHandler &h) {
return std::make_pair(h.GetParameter().GetName(), i++ == current_handler_index ? h.GetNextValue() : h.GetCurrentValue());
});
}
} else {
AnnealingParameterHandler &h = handlers.at(current_handler_index);
const OptimizationParameterResult &last = results.at(0);
const OptimizationParameterResult &before_last = results.at(1);
double temp = h.GetCurrentTemp();
double delta_e = last.GetMetricsAfter() - before_last.GetMetricsAfter();
double et = 1.0 / (1.0 + std::exp(delta_e / temp));
//double h = std::exp(-delta_e / temp);
double alpha = h.GetRandom();
int i = 0;
std::transform(handlers.begin(), handlers.end(), points.begin(), [this, &i](const AnnealingParameterHandler &h) {
return std::make_pair(h.GetParameter().GetName(), i++ == current_handler_index ? h.GetNextValue() : h.GetCurrentValue());
});
return OptimizationParametersSuggestion(handlers.at(current_handler_index).GetParameter(), space.GetPoints(), space.GetMetrics(), points);
}
if (last.IsGood() && ((delta_e < 0.0) || alpha < et)) {
double update_value = last.GetPointsAfter().at(current_handler_index).second;
h.SetValue(update_value);
}
void AnnealingOptimizer::UpdateSpaceWithLatestResults() {
AnnealingParameterHandler &h = handlers.at(current_handler_index);
const OptimizationParameterResult &last = results.at(0);
current_handler_index = (current_handler_index + 1) % (handlers.size());
double temp = h.GetCurrentTemp();
double delta_e = last.GetMetricsAfter() - last.GetMetricsBefore();
double et = 1.0 / (1.0 + std::exp(delta_e / temp));
double alpha = h.GetRandom();
int i = 0;
std::transform(handlers.begin(), handlers.end(), points.begin(), [this, &i](AnnealingParameterHandler &h) {
return std::make_pair(h.GetParameter().GetName(), i++ == current_handler_index ? h.GetNextValue() : h.GetCurrentValue());
});
if (last.IsGood() && (last.GetMetricsBefore() < 0.0 || ((delta_e < 0.0) || alpha < et))) {
double update_value = last.GetPointsAfter().at(current_handler_index).second;
h.SetValue(update_value);
space.Update(current_handler_index, update_value, last.GetMetricsAfter());
}
return OptimizationParametersSuggestion(handlers.at(current_handler_index).GetParameter(), GetCurrentPoints(), points);
}
const OptimizationParameterPoints AnnealingOptimizer::GetCurrentPoints() const noexcept {
OptimizationParameterPoints points(space.GetParameters().size());
std::transform(handlers.cbegin(), handlers.cend(), points.begin(), [](const AnnealingParameterHandler &handler) {
return std::make_pair(handler.GetParameter().GetName(), handler.GetCurrentValue());
});
return points;
current_handler_index = (current_handler_index + 1) % (handlers.size());
}
AnnealingOptimizer::~AnnealingOptimizer() {}
......
......@@ -85,14 +85,14 @@ namespace TTSP {
std::size_t current_handler_index;
std::vector<AnnealingParameterHandler> handlers;
std::vector<double> values;
protected:
void UpdateSpaceWithLatestResults() override;
public:
AnnealingOptimizer(const OptimizationParametersSpace &space, const OptimizerProperties &properties, std::size_t buffer_capacity);
OptimizationParametersSuggestion Suggest(const std::function<OptimizationFunctionInvokeResult(const OptimizationParameterPoints &,
const OptimizationParameterPoints &,
void *)> &invoke, void *data) override;
const OptimizationParameterPoints GetCurrentPoints() const noexcept override;
void *)> &invoke, void *data) const override;
virtual ~AnnealingOptimizer();
};
......
......@@ -12,7 +12,7 @@ namespace TTSP {
OptimizationParametersSuggestion BruteforceOptimizer::Suggest(const std::function<OptimizationFunctionInvokeResult(const OptimizationParameterPoints &,
const OptimizationParameterPoints &,
void *)> &invoke, void *data) {
void *)> &invoke, void *data) const {
const OptimizationParameters &parameters = space.GetParameters();
const OptimizationParameterPoints &before = space.GetPoints();
......@@ -46,11 +46,7 @@ namespace TTSP {
return std::make_pair(entry.first.GetName(), best_value);
});
return OptimizationParametersSuggestion(parameters.at(0).first, GetCurrentPoints(), output);
}
const OptimizationParameterPoints BruteforceOptimizer::GetCurrentPoints() const noexcept {
return space.GetPoints();
return OptimizationParametersSuggestion(parameters.at(0).first, space.GetPoints(), space.GetMetrics(), output);
}
BruteforceOptimizer::~BruteforceOptimizer() {}
......
......@@ -15,9 +15,7 @@ namespace TTSP {
OptimizationParametersSuggestion Suggest(const std::function<OptimizationFunctionInvokeResult(const OptimizationParameterPoints &,
const OptimizationParameterPoints &,
void *)> &invoke, void *data) override;
const OptimizationParameterPoints GetCurrentPoints() const noexcept override;
void *)> &invoke, void *data) const override;
virtual ~BruteforceOptimizer();
};
......
......@@ -11,7 +11,7 @@ namespace TTSP {
OptimizationParametersSuggestion NoopOptimizer::Suggest(const std::function<OptimizationFunctionInvokeResult(const OptimizationParameterPoints &,
const OptimizationParameterPoints &,
void *)> &invoke, void *data) {
void *)> &invoke, void *data) const {
const OptimizationParameters &parameters = space.GetParameters();
OptimizationParameterPoints output(parameters.size());
......@@ -20,11 +20,7 @@ namespace TTSP {
return std::make_pair(entry.first.GetName(), entry.first.GetDefaultValue());
});
return OptimizationParametersSuggestion(parameters.at(0).first, GetCurrentPoints(), output);
}
const OptimizationParameterPoints NoopOptimizer::GetCurrentPoints() const noexcept {
return space.GetPoints();
return OptimizationParametersSuggestion(parameters.at(0).first, space.GetPoints(), space.GetMetrics(), output);
}
NoopOptimizer::~NoopOptimizer() {}
......
......@@ -15,9 +15,7 @@ namespace TTSP {
OptimizationParametersSuggestion Suggest(const std::function<OptimizationFunctionInvokeResult(const OptimizationParameterPoints &,
const OptimizationParameterPoints &,
void *)> &invoke, void *data) override;
const OptimizationParameterPoints GetCurrentPoints() const noexcept override;
void *)> &invoke, void *data) const override;
virtual ~NoopOptimizer();
};
......
......@@ -78,9 +78,10 @@ namespace TTSP {
return default_value;
}
OptimizationParametersSuggestion::OptimizationParametersSuggestion(const OptimizationParameter &changed, const OptimizationParameterPoints &before,
OptimizationParametersSuggestion::OptimizationParametersSuggestion(const OptimizationParameter &changed,
const OptimizationParameterPoints &before, double metrics_before,
const OptimizationParameterPoints &after) :
changed(changed), before(before), after(after) {}
changed(changed), before(before), metrics_before(metrics_before), after(after) {}
const OptimizationParameter &OptimizationParametersSuggestion::GetChangedParameter() const noexcept {
return changed;
......@@ -90,6 +91,10 @@ namespace TTSP {
return before;
}
double OptimizationParametersSuggestion::GetMetricsBefore() const noexcept {
return metrics_before;
}
const OptimizationParameterPoints &OptimizationParametersSuggestion::GetPointsAfter() const noexcept {
return after;
}
......@@ -98,15 +103,17 @@ namespace TTSP {
std::swap(left.solver_name, right.solver_name);
std::swap(left.solver_prefix, right.solver_prefix);
std::swap(left.parameters, right.parameters);
std::swap(left.metrics, right.metrics);
}
OptimizationParametersSpace::OptimizationParametersSpace(const std::string &solver_name,
const std::string &solver_prefix,
const OptimizationParameters &parameters) :
solver_name(solver_name), solver_prefix(solver_prefix), parameters(parameters) {}
const OptimizationParameters &parameters,
double metrics) :
solver_name(solver_name), solver_prefix(solver_prefix), parameters(parameters), metrics(metrics) {}
OptimizationParametersSpace::OptimizationParametersSpace(const OptimizationParametersSpace &other) :
solver_name(other.solver_name), solver_prefix(other.solver_prefix), parameters(other.parameters) {}
solver_name(other.solver_name), solver_prefix(other.solver_prefix), parameters(other.parameters), metrics(other.metrics) {}
OptimizationParametersSpace::OptimizationParametersSpace(OptimizationParametersSpace &&other) noexcept {
OptimizationParametersSpace::swap(*this, other);
......@@ -138,6 +145,14 @@ namespace TTSP {
return parameters;
}
const OptimizationParametersEntry &OptimizationParametersSpace::GetParameterEntry(std::size_t index) const {
return parameters.at(index);
}
const OptimizationParameter &OptimizationParametersSpace::GetParameter(std::size_t index) const {
return GetParameterEntry(index).first;
}
const OptimizationParameterPoints OptimizationParametersSpace::GetPoints() const noexcept {
OptimizationParameterPoints points(parameters.size());
std::transform(parameters.begin(), parameters.end(), points.begin(), [](const OptimizationParametersEntry &p) {
......@@ -146,6 +161,10 @@ namespace TTSP {
return points;
}
double OptimizationParametersSpace::GetMetrics() const noexcept {
return metrics;
}
const OptimizationParameterPoints OptimizationParametersSpace::GetPointsWithChangedParameter(const OptimizationParameter &parameter,
double value) const noexcept {
OptimizationParameterPoints points(parameters.size());
......@@ -155,10 +174,17 @@ namespace TTSP {
return points;
}
void OptimizationParametersSpace::Update(const OptimizationParameterPoints &update) {
void OptimizationParametersSpace::Update(const OptimizationParameterPoints &update, double metrics) {
for (int i = 0; i < update.size(); ++i) {
parameters[i].second = update[i].second;
this->parameters[i].second = update[i].second;
}
this->metrics = metrics;
}
void OptimizationParametersSpace::Update(std::size_t index, double value, double metrics) {
this->parameters[index].second = value;
this->metrics = metrics;
}
void OptimizationParameterResult::swap(OptimizationParameterResult &left, OptimizationParameterResult &right) {
......@@ -273,25 +299,34 @@ namespace TTSP {
});
}
void OptimizerInterface::UpdateSpaceWithLatestResults() {
if (!results.IsEmpty()) {
const OptimizationParameterResult &result = (*results.begin());
space.Update(result.GetPointsAfter(), result.GetMetricsAfter());
}
}
void OptimizerInterface::SaveResult(const OptimizationParameter &changed,
const OptimizationParameterPoints &before, double metrics_before,
const OptimizationParameterPoints &after, double metrics_after, bool is_good) {
results.push(OptimizationParameterResult(changed, before, after, metrics_before, metrics_after, is_good));
if (is_good) {
this->UpdateSpaceWithLatestResults();
}
}
void OptimizerInterface::SaveResult(const OptimizationParameter &changed,
const OptimizationParameterPoints &before,
const OptimizationParameterPoints &after,
double metrics_after, bool is_good) {
results.push(
OptimizationParameterResult(changed, before, after, results.IsEmpty() ? -1.0 : (*results.begin()).GetMetricsAfter(), metrics_after, is_good)
);
void OptimizerInterface::SaveResult(const OptimizationParameter &changed, const OptimizationParameterPoints &after, double metrics_after, bool is_good) {
SaveResult(changed, space.GetPoints(), space.GetMetrics(), after, metrics_after, is_good);
}
const OptimizationParameterResultsBuffer &OptimizerInterface::GetResults() const noexcept {
return results;
};
const OptimizationParameterPoints OptimizerInterface::GetPoints() const noexcept {
return space.GetPoints();
}
void OptimizerInterface::SetVerbosityLevel(OptimizerVerbosityLevel level) noexcept {
verbosity = level;
}
......@@ -300,10 +335,6 @@ namespace TTSP {
return verbosity;
}
void OptimizerInterface::SetProperty(const std::string &name, const std::string &value) {
properties[name] = value;
}
bool OptimizerInterface::HasProperty(const std::string &name) const noexcept {
return properties.find(name) != properties.end();
}
......@@ -312,10 +343,6 @@ namespace TTSP {
return properties.at(name);
}
void OptimizerInterface::UpdateSpacePoints(const OptimizationParameterPoints &update) {
space.Update(update);
}
bool OptimizerInterface::IsOptimizerAvailable(const std::string &type) {
std::vector<std::string> available = OptimizerInterface::GetAvailableOptimizers();
return std::find(available.begin(), available.end(), type) != available.end();
......
......@@ -110,15 +110,19 @@ namespace TTSP {
private:
const OptimizationParameter &changed;
OptimizationParameterPoints before;
double metrics_before;
OptimizationParameterPoints after;
public:
OptimizationParametersSuggestion(const OptimizationParameter &changed,
const OptimizationParameterPoints &before, const OptimizationParameterPoints &after);
const OptimizationParameterPoints &before, double metrics_before,
const OptimizationParameterPoints &after);
const OptimizationParameter &GetChangedParameter() const noexcept;
const OptimizationParameterPoints &GetPointsBefore() const noexcept;
double GetMetricsBefore() const noexcept;
const OptimizationParameterPoints &GetPointsAfter() const noexcept;
};
......@@ -128,7 +132,8 @@ namespace TTSP {
private:
std::string solver_name; /// A name of a solver to which parameters are belong to
std::string solver_prefix; /// Solver prefix
OptimizationParameters parameters; /// List of optimization parameters in this space
OptimizationParameters parameters; /// List of optimization parameters in this space
double metrics; /// Metrics value for current optimization parameters
static void swap(OptimizationParametersSpace &left, OptimizationParametersSpace &right);
......@@ -138,7 +143,7 @@ namespace TTSP {
/// @param solver_prefix - Solver prefix
/// @param parameters - List of optimization parameters in this space
OptimizationParametersSpace(const std::string &solver_name, const std::string &solver_prefix,
const OptimizationParameters &parameters);
const OptimizationParameters &parameters, double metrics);
/// Copy constructor
/// @param other - OptimizationParametersSpace to make copy of
......@@ -169,13 +174,24 @@ namespace TTSP {
/// Getter for parameters of this space
const OptimizationParameters &GetParameters() const noexcept;
/// Getter for parameter entry of this space by index
const OptimizationParametersEntry &GetParameterEntry(std::size_t index) const;
/// Getter for parameter reference of this space by index
const OptimizationParameter &GetParameter(std::size_t index) const;
/// Getter for slice of parameters of this space
const OptimizationParameterPoints GetPoints() const noexcept;
/// Getter for metrics for current parameters of this space
double GetMetrics() const noexcept;
/// Getter for slice of parameters of this space with changed parameter
const OptimizationParameterPoints GetPointsWithChangedParameter(const OptimizationParameter &parameter, double value) const noexcept;
void Update(const OptimizationParameterPoints &update);
void Update(const OptimizationParameterPoints &update, double metrics);
void Update(std::size_t index, double value, double metrics);
};
/// This class is used to store timings result for some optimization parameter points
......@@ -298,39 +314,36 @@ namespace TTSP {
protected:
OptimizationParameterResultsBuffer results;
OptimizationParametersSpace space;
OptimizerProperties properties;
const OptimizerProperties properties;
virtual void UpdateSpaceWithLatestResults();
public:
OptimizerInterface(const OptimizationParametersSpace &space, const OptimizerProperties &properties, std::size_t buffer_capacity) :
space(space), properties(properties), results(buffer_capacity) {};
virtual OptimizationParametersSuggestion Suggest(const std::function<OptimizationFunctionInvokeResult(const OptimizationParameterPoints &,
const OptimizationParameterPoints &,
void *)> &invoke, void *data) = 0;
virtual const OptimizationParameterPoints GetCurrentPoints() const noexcept = 0;
void *)> &invoke, void *data) const = 0;
void SaveResult(const OptimizationParameter &changed,
const OptimizationParameterPoints &before, double metrics_before,
const OptimizationParameterPoints &after, double metrics_after, bool is_good);
void SaveResult(const OptimizationParameter &changed,
const OptimizationParameterPoints &before,
const OptimizationParameterPoints &after, double metrics_after, bool is_good);
void SaveResult(const OptimizationParameter &changed, const OptimizationParameterPoints &after, double metrics_after, bool is_good);