Skip to content

Commit

Permalink
Make infeasibily more changeable : add use of a factory and remove th…
Browse files Browse the repository at this point in the history
…e clone function
  • Loading branch information
guilpier-code committed Jul 8, 2024
1 parent 64f94d8 commit d83e592
Show file tree
Hide file tree
Showing 6 changed files with 75 additions and 108 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -40,16 +40,6 @@ static bool compareSlackSolutions(const MPVariable* a, const MPVariable* b)

namespace Antares::Optimization
{
ConstraintSlackAnalysis::ConstraintSlackAnalysis()
{
watchedConstraintTypes_.push_back(std::make_shared<HourlyBC>());
watchedConstraintTypes_.push_back(std::make_shared<DailyBC>());
watchedConstraintTypes_.push_back(std::make_shared<WeeklyBC>());
watchedConstraintTypes_.push_back(std::make_shared<FictitiousLoad>());
watchedConstraintTypes_.push_back(std::make_shared<HydroLevel>());
watchedConstraintTypes_.push_back(std::make_shared<STS>());
watchedConstraintTypes_.push_back(std::make_shared<HydroProduction>());
}

void ConstraintSlackAnalysis::run(MPSolver* problem)
{
Expand Down Expand Up @@ -78,13 +68,7 @@ void ConstraintSlackAnalysis::run(MPSolver* problem)

void ConstraintSlackAnalysis::selectConstraintsToWatch(MPSolver* problem)
{
std::vector<std::string> patterns;
std::for_each(watchedConstraintTypes_.begin(),
watchedConstraintTypes_.end(),
[&](auto& c) { patterns.push_back(c->regexId()); });
std::string constraint_name_pattern{boost::algorithm::join(patterns, "|")};

std::regex rgx(constraint_name_pattern);
std::regex rgx = constraintFactory_.regexFilter();
for (MPConstraint* c: problem->constraints())
{
if (std::regex_search(c->name(), rgx))
Expand Down Expand Up @@ -148,7 +132,7 @@ void ConstraintSlackAnalysis::trimSlackVariables()

void ConstraintSlackAnalysis::printReport() const
{
InfeasibleProblemReport report(slackVariables_, watchedConstraintTypes_);
InfeasibleProblemReport report(slackVariables_, constraintFactory_);
report.logSuspiciousConstraints();
report.logInfeasibilityCauses();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,6 @@ namespace Antares::Optimization
class ConstraintSlackAnalysis: public UnfeasibilityAnalysis
{
public:
ConstraintSlackAnalysis();
~ConstraintSlackAnalysis() override = default;

void run(operations_research::MPSolver* problem) override;
Expand All @@ -62,7 +61,7 @@ class ConstraintSlackAnalysis: public UnfeasibilityAnalysis

std::vector<operations_research::MPConstraint*> constraintsToWatch_;
std::vector<const operations_research::MPVariable*> slackVariables_;
std::vector<std::shared_ptr<WatchedConstraint>> watchedConstraintTypes_;
ConstraintsFactory constraintFactory_;
const unsigned int nbMaxSlackVarsToKeep = 10;
};

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,15 +43,15 @@ class InfeasibleProblemReport
InfeasibleProblemReport() = delete;
explicit InfeasibleProblemReport(
const std::vector<const operations_research::MPVariable*>& slackVariables,
const std::vector<std::shared_ptr<WatchedConstraint>>&);
const ConstraintsFactory&);
void logSuspiciousConstraints();
void logInfeasibilityCauses();

private:
void buildConstraintsFromSlackVars();
void filterConstraintsToOneByType();

const std::vector<std::shared_ptr<WatchedConstraint>>& constraintTypes_;
const ConstraintsFactory& constraintsFactory_;
const std::vector<const MPVariable*>& slackVariables_;
std::vector<std::shared_ptr<WatchedConstraint>> constraints_;
std::vector<std::shared_ptr<WatchedConstraint>> uniqueConstraintByType_;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,88 +4,91 @@
#include <memory>
#include <string>
#include <vector>
#include <regex>

namespace Antares::Optimization
{
class WatchedConstraint
{
public:
void setConstraintName(std::string constraintName);
WatchedConstraint(std::string constraintName);
std::string regexId() const;
virtual std::shared_ptr<WatchedConstraint> clone() const = 0;
virtual std::string infeasisibity() = 0;
virtual std::string infeasisibityCause() = 0;

protected:
void setRegexId(std::string name);
const std::vector<std::string>& splitName() const;

private:
std::string name_;
protected:
std::string constraintName_;
std::string regexId_;
std::vector<std::string> splitName_;
};

class HourlyBC: public WatchedConstraint
{
public:
HourlyBC();
std::shared_ptr<WatchedConstraint> clone() const override;
HourlyBC(std::string constraintName);
std::string infeasisibity() override;
std::string infeasisibityCause() override;
};

class DailyBC: public WatchedConstraint
{
public:
DailyBC();
std::shared_ptr<WatchedConstraint> clone() const override;
DailyBC(std::string constraintName);
std::string infeasisibity() override;
std::string infeasisibityCause() override;
};

class WeeklyBC: public WatchedConstraint
{
public:
WeeklyBC();
std::shared_ptr<WatchedConstraint> clone() const override;
WeeklyBC(std::string constraintName);
std::string infeasisibity() override;
std::string infeasisibityCause() override;
};

class FictitiousLoad: public WatchedConstraint
{
public:
FictitiousLoad();
std::shared_ptr<WatchedConstraint> clone() const override;
FictitiousLoad(std::string constraintName);
std::string infeasisibity() override;
std::string infeasisibityCause() override;
};

class HydroLevel: public WatchedConstraint
{
public:
HydroLevel();
std::shared_ptr<WatchedConstraint> clone() const override;
HydroLevel(std::string constraintName);
std::string infeasisibity() override;
std::string infeasisibityCause() override;
};

class STS: public WatchedConstraint
{
public:
STS();
std::shared_ptr<WatchedConstraint> clone() const override;
STS(std::string constraintName);
std::string infeasisibity() override;
std::string infeasisibityCause() override;
};

class HydroProduction: public WatchedConstraint
{
public:
std::shared_ptr<WatchedConstraint> clone() const override;
HydroProduction();
HydroProduction(std::string constraintName);
std::string infeasisibity() override;
std::string infeasisibityCause() override;
};

class ConstraintsFactory
{
public:
std::shared_ptr<WatchedConstraint> create(std::string regexId) const;
std::regex regexFilter();
private:
const std::vector<std::string> regex_ids_ = {"::hourly::", "::daily::", "::weekly::", "^FictiveLoads::",
"^AreaHydroLevel::", "^Level::", "^HydroPower::"};
};

} // namespace Antares::Optimization
13 changes: 3 additions & 10 deletions src/solver/infeasible-problem-analysis/report.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -29,9 +29,9 @@ namespace Antares::Optimization
{
InfeasibleProblemReport::InfeasibleProblemReport(
const std::vector<const MPVariable*>& slackVariables,
const std::vector<std::shared_ptr<WatchedConstraint>>& constraintTypes):
const ConstraintsFactory& factory):
slackVariables_(slackVariables),
constraintTypes_(constraintTypes)
constraintsFactory_(factory)
{
buildConstraintsFromSlackVars();
filterConstraintsToOneByType();
Expand All @@ -41,14 +41,7 @@ void InfeasibleProblemReport::buildConstraintsFromSlackVars()
{
for (const auto& slackVar: slackVariables_)
{
for (const auto& cType: constraintTypes_)
{
if (std::regex_search(slackVar->name(), std::regex(cType->regexId())))
{
constraints_.push_back(cType->clone());
constraints_.back()->setConstraintName(slackVar->name());
}
}
constraints_.push_back(constraintsFactory_.create(slackVar->name()));
}
}

Expand Down
102 changes: 45 additions & 57 deletions src/solver/infeasible-problem-analysis/watched-constraints.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
#include <boost/algorithm/string.hpp>
#include <boost/algorithm/string/regex.hpp>
#include <boost/regex.hpp>
#include <regex>

class StringIsNotWellFormated: public std::runtime_error
{
Expand Down Expand Up @@ -59,22 +60,16 @@ namespace Antares::Optimization
// =======================================
// Generic constraint logger
// =======================================
void WatchedConstraint::setConstraintName(std::string name)
WatchedConstraint::WatchedConstraint(std::string name) : constraintName_(name)
{
name_ = name;
boost::algorithm::split_regex(splitName_, name_, boost::regex("::"));
boost::algorithm::split_regex(splitName_, constraintName_, boost::regex("::"));
}

std::string WatchedConstraint::regexId() const
{
return regexId_;
}

void WatchedConstraint::setRegexId(std::string regexId)
{
regexId_ = regexId;
}

const std::vector<std::string>& WatchedConstraint::splitName() const
{
return splitName_;
Expand All @@ -83,14 +78,9 @@ const std::vector<std::string>& WatchedConstraint::splitName() const
// =======================================
// Hourly BC logger
// =======================================
HourlyBC::HourlyBC()
HourlyBC::HourlyBC(std::string constraintName) : WatchedConstraint(constraintName)
{
setRegexId("::hourly::");
}

std::shared_ptr<WatchedConstraint> HourlyBC::clone() const
{
return std::make_shared<HourlyBC>(*this);
regexId_ = "::hourly::";
}

std::string HourlyBC::infeasisibity()
Expand All @@ -106,14 +96,9 @@ std::string HourlyBC::infeasisibityCause()
// =======================================
// Daily BC logger
// =======================================
DailyBC::DailyBC()
{
setRegexId("::daily::");
}

std::shared_ptr<WatchedConstraint> DailyBC::clone() const
DailyBC::DailyBC(std::string constraintName) : WatchedConstraint(constraintName)
{
return std::make_shared<DailyBC>(*this);
regexId_ = "::daily::";
}

std::string DailyBC::infeasisibity()
Expand All @@ -129,14 +114,9 @@ std::string DailyBC::infeasisibityCause()
// =======================================
// Weekly BC constraint
// =======================================
WeeklyBC::WeeklyBC()
WeeklyBC::WeeklyBC(std::string constraintName) : WatchedConstraint(constraintName)
{
setRegexId("::weekly::");
}

std::shared_ptr<WatchedConstraint> WeeklyBC::clone() const
{
return std::make_shared<WeeklyBC>(*this);
regexId_ = "::weekly::";
}

std::string WeeklyBC::infeasisibity()
Expand All @@ -152,14 +132,9 @@ std::string WeeklyBC::infeasisibityCause()
// =======================================
// Fictitious load constraint
// =======================================
FictitiousLoad::FictitiousLoad()
{
setRegexId("^FictiveLoads::");
}

std::shared_ptr<WatchedConstraint> FictitiousLoad::clone() const
FictitiousLoad::FictitiousLoad(std::string constraintName) : WatchedConstraint(constraintName)
{
return std::make_shared<FictitiousLoad>(*this);
regexId_ = "^FictiveLoads::";
}

std::string FictitiousLoad::infeasisibity()
Expand All @@ -176,14 +151,9 @@ std::string FictitiousLoad::infeasisibityCause()
// =======================================
// Hydro level constraint
// =======================================
HydroLevel::HydroLevel()
HydroLevel::HydroLevel(std::string constraintName) : WatchedConstraint(constraintName)
{
setRegexId("^AreaHydroLevel::");
}

std::shared_ptr<WatchedConstraint> HydroLevel::clone() const
{
return std::make_shared<HydroLevel>(*this);
regexId_ = "^AreaHydroLevel::";
}

std::string HydroLevel::infeasisibity()
Expand All @@ -201,14 +171,9 @@ std::string HydroLevel::infeasisibityCause()
// =======================================
// Short term storage constraint
// =======================================
STS::STS()
{
setRegexId("^Level::");
}

std::shared_ptr<WatchedConstraint> STS::clone() const
STS::STS(std::string constraintName) : WatchedConstraint(constraintName)
{
return std::make_shared<STS>(*this);
regexId_ = "^Level::";
}

std::string STS::infeasisibity()
Expand All @@ -226,14 +191,9 @@ std::string STS::infeasisibityCause()
// =======================================
// Hydro production constraint
// =======================================
HydroProduction::HydroProduction()
HydroProduction::HydroProduction(std::string constraintName) : WatchedConstraint(constraintName)
{
setRegexId("^HydroPower::");
}

std::shared_ptr<WatchedConstraint> HydroProduction::clone() const
{
return std::make_shared<HydroProduction>(*this);
regexId_ = "^HydroPower::";
}

std::string HydroProduction::infeasisibity()
Expand All @@ -245,4 +205,32 @@ std::string HydroProduction::infeasisibityCause()
{
return "* impossible to generate exactly the weekly hydro target";
}

// =======================================
// Constraints factory
// =======================================
std::shared_ptr<WatchedConstraint> ConstraintsFactory::create(std::string varName) const
{
if (std::regex_search(varName, std::regex("::hourly::")))
return std::make_shared<HourlyBC>(varName);
if (std::regex_search(varName, std::regex("::daily::")))
return std::make_shared<DailyBC>(varName);
if (std::regex_search(varName, std::regex("::weekly::")))
return std::make_shared<WeeklyBC>(varName);
if (std::regex_search(varName, std::regex("^FictiveLoads::")))
return std::make_shared<FictitiousLoad>(varName);
if (std::regex_search(varName, std::regex("^AreaHydroLevel::")))
return std::make_shared<HydroLevel>(varName);
if (std::regex_search(varName, std::regex("^Level::")))
return std::make_shared<STS>(varName);
if (std::regex_search(varName, std::regex("^HydroPower::")))
return std::make_shared<HydroProduction>(varName);
return nullptr;
}

std::regex ConstraintsFactory::regexFilter()
{
return std::regex(boost::algorithm::join(regex_ids_, "|"));
}

} // namespace Antares::Optimization

0 comments on commit d83e592

Please sign in to comment.