Commit 30e592fd authored by Dmitry Bagaev's avatar Dmitry Bagaev
Browse files

Major bug fixes

parent 6c878249
......@@ -171,7 +171,7 @@ int main(int argc, char **argv) {
if (rank == 0) std::cout << "Solving with " << solverName << std::endl;
TTSP::OptimizationParameter tau("tau", std::make_pair(-4, -1), 0.1, 1e-3, TTSP::OptimizationParameterType::EXPONENT);
TTSP::OptimizationParameter tau("tau", std::make_pair(-4, -1), 0.1, -3, TTSP::OptimizationParameterType::EXPONENT);
//TTSP::OptimizationParameter q("q", {0, 1, 2, 3, 4}, 2);
//TTSP::OptimizationParameter eps("eps", {1e-7, 1e-6, 1e-5, 1e-4, 1e-3}, 1e-5);
TTSP::OptimizationParameterEntries entries;
......@@ -183,7 +183,7 @@ int main(int argc, char **argv) {
TTSP::OptimizerProperties properties;
properties["tau:use_closest"] = "false";
properties["tau:strict_bound"] = "true";
properties["tau:strict_bound"] = "false";
properties["eps:use_closest"] = "false";
properties["eps:strict_bound"] = "false";
......@@ -205,6 +205,7 @@ int main(int argc, char **argv) {
TTSP::OptimizerInterface *optimizer = TTSP::OptimizerInterface::GetOptimizer(optimizerType, parameters, properties, 50);
optimizer->SetVerbosityLevel(TTSP::OptimizerVerbosityLevel::Level3);
optimizer->SetRestartStrategy(TTSP::OptimizerRestartStrategy::RESTART_WITH_BEST, 10);
while (!series.end()) {
......@@ -265,7 +266,7 @@ int main(int argc, char **argv) {
bool is_good = result.first;
double metrics = result.second;
optimizer->SaveResult(suggestion.GetChangedParameter(), suggestion.GetPointsAfter(), metrics, is_good);
optimizer->SaveResult(suggestion, metrics, is_good);
TTSP::OptimizerVerbosityLevel verbosity = TTSP::OptimizerVerbosityLevel::Level3;
......
......@@ -114,6 +114,7 @@ namespace TTSP {
static void swap(OptimizationParameterPoint &left, OptimizationParameterPoint &right);
static double convert(double value, OptimizationParameterType type);
public:
OptimizationParameterPoint(const OptimizationParameterPoint &other);
......@@ -121,7 +122,7 @@ namespace TTSP {
OptimizationParameterPoint &operator=(const OptimizationParameterPoint &other);
const std::string& GetName() const noexcept;
const std::string &GetName() const noexcept;
double GetValue() const noexcept;
......@@ -145,16 +146,19 @@ namespace TTSP {
/// @see OptimizationParameters
class OptimizationParametersSuggestion {
private:
const OptimizationParameter &changed;
std::size_t changed_index;
double changed_value;
OptimizationParameterPoints before;
double metrics_before;
OptimizationParameterPoints after;
public:
OptimizationParametersSuggestion(const OptimizationParameter &changed,
OptimizationParametersSuggestion(std::size_t changed_index, double changed_value,
const OptimizationParameterPoints &before, double metrics_before,
const OptimizationParameterPoints &after);
const OptimizationParameter &GetChangedParameter() const noexcept;
std::size_t GetChangedParameterIndex() const noexcept;
double GetChangedValue() const noexcept;
const OptimizationParameterPoints &GetPointsBefore() const noexcept;
......@@ -211,7 +215,7 @@ namespace TTSP {
/// 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, double metrics);
void Update(const std::vector<double> &update, double metrics);
void Update(std::size_t index, double value, double metrics);
};
......@@ -219,7 +223,8 @@ namespace TTSP {
/// This class is used to store timings result for some optimization parameter points
class OptimizationParameterResult {
private:
const OptimizationParameter &changed; /// Changed optimization parameter reference
std::size_t changed_index; /// Changed optimization parameter index
double changed_value; /// New changed value for 'changed' parameter
OptimizationParameterPoints before; /// Optimization parameter points before changing
double metrics_before; /// Optimization metrics before changing
OptimizationParameterPoints after; /// Optimization parameter points after changing
......@@ -230,11 +235,8 @@ namespace TTSP {
public:
/// Default constructor to define an OptimizationParameterResult
/// @param points - Optimization parameter points to store result for
/// @param preconditioner_time - Preconditioner timings
/// @param solve_time - Solve timings
/// @param is_solved - Is problem solved or not
OptimizationParameterResult(const OptimizationParameter &changed, const OptimizationParameterPoints &before, const OptimizationParameterPoints &after,
OptimizationParameterResult(std::size_t changed_index, double changed_value,
const OptimizationParameterPoints &before, const OptimizationParameterPoints &after,
double metrics_before, double metrics_after, bool is_good);
/// Copy constructor
......@@ -263,6 +265,12 @@ namespace TTSP {
/// Getter for is solved status
bool IsGood() const noexcept;
/// Getter for changed parameter
std::size_t GetChangedParameterIndex() const noexcept;
/// Getter for new changed value
double GetChangedValue() const noexcept;
};
/// This class is used to store last N solve results and used parameters on it
......@@ -321,24 +329,36 @@ namespace TTSP {
typedef std::map<std::string, std::string> OptimizerProperties;
enum OptimizerVerbosityLevel {
enum class OptimizerVerbosityLevel {
Level0,
Level1,
Level2,
Level3
};
enum class OptimizerRestartStrategy {
NO_RESTART,
RESTART_WITH_BEST
};
typedef std::pair<bool, double> OptimizationFunctionInvokeResult;
class OptimizerInterface {
private:
OptimizerVerbosityLevel verbosity = OptimizerVerbosityLevel::Level0;
OptimizerRestartStrategy restart_strategy = OptimizerRestartStrategy::NO_RESTART;
std::size_t max_fails = std::numeric_limits<std::size_t>::max();
std::size_t fails_count = 0;
void RestartWithBestStrategy();
protected:
OptimizationParameterResultsBuffer results;
OptimizationParameters parameters;
const OptimizerProperties properties;
virtual void UpdateSpaceWithLatestResults();
virtual bool UpdateSpaceWithLatestResults();
virtual OptimizationAlgorithmSuggestion AlgorithmMakeSuggestion(const std::function<OptimizationFunctionInvokeResult(const OptimizationParameterPoints &,
const OptimizationParameterPoints &,
......@@ -352,11 +372,13 @@ namespace TTSP {
const OptimizationParameterPoints &,
void *)> &invoke, void *data) const;
void SaveResult(const OptimizationParameter &changed,
void SaveResult(std::size_t changed_index, double changed_value,
const OptimizationParameterPoints &before, double metrics_before,
const OptimizationParameterPoints &after, double metrics_after, bool is_good);
void SaveResult(const OptimizationParameter &changed, const OptimizationParameterPoints &after, double metrics_after, bool is_good);
void SaveResult(std::size_t changed_index, double changed_value, const OptimizationParameterPoints &after, double metrics_after, bool is_good);
void SaveResult(const OptimizationParametersSuggestion &suggestion, double metrics, bool is_good);
const OptimizationParameterResultsBuffer &GetResults() const noexcept;
......@@ -370,6 +392,8 @@ namespace TTSP {
const std::string &GetProperty(const std::string &name) const;
void SetRestartStrategy(OptimizerRestartStrategy strategy, std::size_t max_fails) noexcept;
virtual ~OptimizerInterface() {};
static bool IsOptimizerAvailable(const std::string &type);
......
......@@ -80,18 +80,23 @@ namespace TTSP {
return std::make_pair(current_handler_index, handler.GetParameter().GetValues().at(handler.NextIndex()));
}
void AlternatingOptimizer::UpdateSpaceWithLatestResults() {
bool AlternatingOptimizer::UpdateSpaceWithLatestResults() {
AlternatingParameterHandler &current = handlers.at(current_handler_index);
const OptimizationParameterResult &last = results.at(0);
bool is_updated = false;
if (last.IsGood() && (last.GetMetricsBefore() < 0.0 || last.GetMetricsAfter() < last.GetMetricsBefore())) {
current.UpdateIndex(current.NextIndex());
parameters.Update(current_handler_index, parameters.GetParameter(current_handler_index).GetValues().at(current.GetCurrentIndex()), last.GetMetricsAfter());
is_updated = true;
} else {
current.NextDirection();
}
current_handler_index = (current_handler_index + 1) % (handlers.size());
return is_updated;
}
AlternatingOptimizer::~AlternatingOptimizer() {}
......
......@@ -44,7 +44,7 @@ namespace TTSP {
std::size_t current_handler_index;
std::vector<AlternatingParameterHandler> handlers;
protected:
void UpdateSpaceWithLatestResults() override;
bool UpdateSpaceWithLatestResults() override;
OptimizationAlgorithmSuggestion AlgorithmMakeSuggestion(const std::function<OptimizationFunctionInvokeResult(const OptimizationParameterPoints &,
const OptimizationParameterPoints &,
......
......@@ -200,7 +200,7 @@ namespace TTSP {
return std::make_pair(current_handler_index, handlers.at(current_handler_index).GetNextValue());
}
void AnnealingOptimizer::UpdateSpaceWithLatestResults() {
bool AnnealingOptimizer::UpdateSpaceWithLatestResults() {
AnnealingParameterHandler &h = handlers.at(current_handler_index);
const OptimizationParameterResult &last = results.at(0);
......@@ -209,13 +209,18 @@ namespace TTSP {
double et = 1.0 / (1.0 + std::exp(delta_e / temp));
double alpha = h.GetRandom();
bool is_updated = false;
if (last.IsGood() && (last.GetMetricsBefore() < 0.0 || ((delta_e < 0.0) || alpha < et))) {
double update_value = last.GetPointsAfter().at(current_handler_index).GetValue();
double update_value = last.GetChangedValue();
h.SetValue(update_value);
parameters.Update(current_handler_index, update_value, last.GetMetricsAfter());
is_updated = true;
}
current_handler_index = (current_handler_index + 1) % (handlers.size());
return is_updated;
}
AnnealingOptimizer::~AnnealingOptimizer() {}
......
......@@ -76,7 +76,7 @@ namespace TTSP {
std::size_t current_handler_index;
std::vector<AnnealingParameterHandler> handlers;
protected:
void UpdateSpaceWithLatestResults() override;
bool UpdateSpaceWithLatestResults() override;
OptimizationAlgorithmSuggestion AlgorithmMakeSuggestion(const std::function<OptimizationFunctionInvokeResult(const OptimizationParameterPoints &,
const OptimizationParameterPoints &,
......
......@@ -40,11 +40,12 @@ namespace TTSP {
return std::make_pair(current_index, best_value);
}
void BruteforceOptimizer::UpdateSpaceWithLatestResults() {
bool BruteforceOptimizer::UpdateSpaceWithLatestResults() {
const OptimizationParameterResult &last = results.at(0);
if (last.IsGood()) {
parameters.Update(current_index, last.GetPointsAfter().at(current_index).GetValue(), last.GetMetricsAfter());
}
return true;
}
BruteforceOptimizer::~BruteforceOptimizer() {}
......
......@@ -13,7 +13,7 @@ namespace TTSP {
private:
std::size_t current_index;
protected:
void UpdateSpaceWithLatestResults() override;
bool UpdateSpaceWithLatestResults() override;
OptimizationAlgorithmSuggestion AlgorithmMakeSuggestion(const std::function<OptimizationFunctionInvokeResult(const OptimizationParameterPoints &,
const OptimizationParameterPoints &,
......
......@@ -121,13 +121,17 @@ namespace TTSP {
OptimizationParameterPoint::~OptimizationParameterPoint() {}
OptimizationParametersSuggestion::OptimizationParametersSuggestion(const OptimizationParameter &changed,
OptimizationParametersSuggestion::OptimizationParametersSuggestion(std::size_t changed_index, double changed_value,
const OptimizationParameterPoints &before, double metrics_before,
const OptimizationParameterPoints &after) :
changed(changed), before(before), metrics_before(metrics_before), after(after) {}
changed_index(changed_index), changed_value(changed_value), before(before), metrics_before(metrics_before), after(after) {}
const OptimizationParameter &OptimizationParametersSuggestion::GetChangedParameter() const noexcept {
return changed;
std::size_t OptimizationParametersSuggestion::GetChangedParameterIndex() const noexcept {
return changed_index;
}
double OptimizationParametersSuggestion::GetChangedValue() const noexcept {
return changed_value;
}
const OptimizationParameterPoints &OptimizationParametersSuggestion::GetPointsBefore() const noexcept {
......@@ -206,9 +210,9 @@ namespace TTSP {
return points;
}
void OptimizationParameters::Update(const OptimizationParameterPoints &update, double metrics) {
void OptimizationParameters::Update(const std::vector<double> &update, double metrics) {
for (int i = 0; i < update.size(); ++i) {
this->entries[i].second = update[i].GetValue();
this->entries[i].second = update[i];
}
this->metrics = metrics;
......@@ -220,6 +224,8 @@ namespace TTSP {
}
void OptimizationParameterResult::swap(OptimizationParameterResult &left, OptimizationParameterResult &right) {
std::swap(left.changed_index, right.changed_index);
std::swap(left.changed_value, right.changed_value);
std::swap(left.before, right.before);
std::swap(left.metrics_before, right.metrics_before);
std::swap(left.after, right.after);
......@@ -227,16 +233,17 @@ namespace TTSP {
std::swap(left.is_good, right.is_good);
}
OptimizationParameterResult::OptimizationParameterResult(const OptimizationParameter &changed, const OptimizationParameterPoints &before,
const OptimizationParameterPoints &after,
OptimizationParameterResult::OptimizationParameterResult(std::size_t changed_index, double changed_value,
const OptimizationParameterPoints &before, const OptimizationParameterPoints &after,
double metrics_before, double metrics_after, bool is_good) :
changed(changed), before(before), after(after), metrics_before(metrics_before), metrics_after(metrics_after), is_good(is_good) {}
changed_index(changed_index), changed_value(changed_value),
before(before), after(after), metrics_before(metrics_before), metrics_after(metrics_after), is_good(is_good) {}
OptimizationParameterResult::OptimizationParameterResult(const OptimizationParameterResult &other) :
changed(other.changed), before(other.before), after(other.after),
changed_index(other.changed_index), changed_value(other.changed_value), before(other.before), after(other.after),
metrics_before(other.metrics_before), metrics_after(other.metrics_after), is_good(other.is_good) {}
OptimizationParameterResult::OptimizationParameterResult(OptimizationParameterResult &&other) noexcept : changed(std::move(other).changed) {
OptimizationParameterResult::OptimizationParameterResult(OptimizationParameterResult &&other) noexcept {
OptimizationParameterResult::swap(*this, other);
}
......@@ -266,6 +273,15 @@ namespace TTSP {
return is_good;
}
std::size_t OptimizationParameterResult::GetChangedParameterIndex() const noexcept {
return changed_index;
}
/// Getter for new changed value
double OptimizationParameterResult::GetChangedValue() const noexcept {
return changed_value;
}
void OptimizationParameterResultsBuffer::swap(OptimizationParameterResultsBuffer &left,
OptimizationParameterResultsBuffer &right) {
......@@ -331,11 +347,23 @@ namespace TTSP {
});
}
void OptimizerInterface::UpdateSpaceWithLatestResults() {
void OptimizerInterface::RestartWithBestStrategy() {
auto min = std::min_element(results.cbegin(), results.cbegin() + max_fails, [](const OptimizationParameterResult &l, const OptimizationParameterResult &r) {
return l.GetMetricsAfter() < r.GetMetricsAfter();
});
results.push(OptimizationParameterResult(*min));
parameters.Update(min->GetChangedParameterIndex(), min->GetChangedValue(), min->GetMetricsAfter());
this->fails_count = 0;
}
bool OptimizerInterface::UpdateSpaceWithLatestResults() {
if (!results.IsEmpty()) {
const OptimizationParameterResult &result = (*results.cbegin());
parameters.Update(result.GetPointsAfter(), result.GetMetricsAfter());
const OptimizationParameterResult &last = results.at(0);
parameters.Update(last.GetChangedParameterIndex(), last.GetChangedValue(), last.GetMetricsAfter());
}
return true;
}
OptimizationParametersSuggestion OptimizerInterface::Suggest(const std::function<OptimizationFunctionInvokeResult(const OptimizationParameterPoints &,
......@@ -344,24 +372,46 @@ namespace TTSP {
OptimizationAlgorithmSuggestion algorithm = this->AlgorithmMakeSuggestion(invoke, data);
return OptimizationParametersSuggestion(
parameters.GetParameter(algorithm.first),
algorithm.first,
algorithm.second,
parameters.GetPoints(),
parameters.GetMetrics(),
parameters.GetPointsWithChangedParameter(parameters.GetParameter(algorithm.first), algorithm.second)
);
}
void OptimizerInterface::SaveResult(const OptimizationParameter &changed,
void OptimizerInterface::SaveResult(std::size_t changed_index, double changed_value,
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();
results.push(OptimizationParameterResult(changed_index, changed_value, before, after, metrics_before, metrics_after, is_good));
bool is_updated = is_good && this->UpdateSpaceWithLatestResults();
if (is_updated) {
this->fails_count = 0;
} else {
this->fails_count += 1;
}
if (this->fails_count > this->max_fails) {
switch (restart_strategy) {
case OptimizerRestartStrategy::NO_RESTART:
break;
case OptimizerRestartStrategy::RESTART_WITH_BEST:
RestartWithBestStrategy();
break;
default:
break;
}
}
}
void OptimizerInterface::SaveResult(const OptimizationParameter &changed, const OptimizationParameterPoints &after, double metrics_after, bool is_good) {
SaveResult(changed, parameters.GetPoints(), parameters.GetMetrics(), after, metrics_after, is_good);
void OptimizerInterface::SaveResult(std::size_t changed_index, double changed_value,
const OptimizationParameterPoints &after, double metrics_after, bool is_good) {
SaveResult(changed_index, changed_value, parameters.GetPoints(), parameters.GetMetrics(), after, metrics_after, is_good);
}
void OptimizerInterface::SaveResult(const OptimizationParametersSuggestion &suggestion, double metrics, bool is_good) {
SaveResult(suggestion.GetChangedParameterIndex(), suggestion.GetChangedValue(), suggestion.GetPointsAfter(), metrics, is_good);
}
const OptimizationParameterResultsBuffer &OptimizerInterface::GetResults() const noexcept {
......@@ -388,6 +438,11 @@ namespace TTSP {
return properties.at(name);
}
void OptimizerInterface::SetRestartStrategy(OptimizerRestartStrategy strategy, std::size_t max_fails) noexcept {
this->restart_strategy = strategy;
this->max_fails = max_fails;
}
bool OptimizerInterface::IsOptimizerAvailable(const std::string &type) {
std::vector<std::string> available = OptimizerInterface::GetAvailableOptimizers();
return std::find(available.cbegin(), available.cend(), type) != available.cend();
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment