-
Notifications
You must be signed in to change notification settings - Fork 24
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Unfeasible problem analyzer: check variable bounds consistency (#1689)
The analyzer has been refactored into a list of particular analysis, to be able to add more in the future.
- Loading branch information
1 parent
a630959
commit 2242747
Showing
21 changed files
with
609 additions
and
211 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,18 +1,25 @@ | ||
project(infeasible-problem-analysis) | ||
|
||
set(SRC_INFEASIBLE_PROBLEM_ANALYSIS | ||
problem.cpp | ||
problem.h | ||
unfeasibility-analysis.h | ||
constraint-slack-analysis.h | ||
constraint-slack-analysis.cpp | ||
variables-bounds-consistency.h | ||
variables-bounds-consistency.cpp | ||
unfeasible-pb-analyzer.cpp | ||
unfeasible-pb-analyzer.h | ||
report.h | ||
report.cpp | ||
constraint.h | ||
constraint.cpp | ||
exceptions.h | ||
exceptions.cpp | ||
) | ||
|
||
add_library(infeasible_problem_analysis ${SRC_INFEASIBLE_PROBLEM_ANALYSIS}) | ||
target_link_libraries(infeasible_problem_analysis | ||
PUBLIC ortools::ortools sirius_solver | ||
utils #ortools-utils, not Antares::utils | ||
) | ||
target_include_directories(infeasible_problem_analysis | ||
PUBLIC | ||
${CMAKE_CURRENT_SOURCE_DIR}/.. | ||
) |
85 changes: 85 additions & 0 deletions
85
src/solver/infeasible-problem-analysis/constraint-slack-analysis.cpp
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,85 @@ | ||
#include <regex> | ||
#include "constraint-slack-analysis.h" | ||
#include <antares/logs/logs.h> | ||
#include "report.h" | ||
|
||
using namespace operations_research; | ||
|
||
namespace Antares::Optimization | ||
{ | ||
|
||
void ConstraintSlackAnalysis::run(MPSolver* problem) | ||
{ | ||
addSlackVariables(problem); | ||
if (slackVariables_.empty()) | ||
{ | ||
logs.error() << title() << " : no constraints have been selected"; | ||
return; | ||
} | ||
|
||
buildObjective(problem); | ||
|
||
const MPSolver::ResultStatus status = problem->Solve(); | ||
if ((status != MPSolver::OPTIMAL) && (status != MPSolver::FEASIBLE)) | ||
{ | ||
logs.error() << title() << " : modified linear problem could not be solved"; | ||
return; | ||
} | ||
|
||
hasDetectedInfeasibilityCause_ = true; | ||
} | ||
|
||
void ConstraintSlackAnalysis::addSlackVariables(MPSolver* problem) | ||
{ | ||
/* Optimization: | ||
We assess that less than 1 every 3 constraint will match | ||
the regex. If more, push_back may force the copy of memory blocks. | ||
This should not happen in most cases. | ||
*/ | ||
const unsigned int selectedConstraintsInverseRatio = 3; | ||
slackVariables_.reserve(problem->NumConstraints() / selectedConstraintsInverseRatio); | ||
std::regex rgx(constraint_name_pattern); | ||
const double infinity = MPSolver::infinity(); | ||
for (MPConstraint* constraint : problem->constraints()) | ||
{ | ||
if (std::regex_search(constraint->name(), rgx)) | ||
{ | ||
if (constraint->lb() != -infinity) | ||
{ | ||
const MPVariable* slack | ||
= problem->MakeNumVar(0, infinity, constraint->name() + "::low"); | ||
constraint->SetCoefficient(slack, 1.); | ||
slackVariables_.push_back(slack); | ||
} | ||
|
||
if (constraint->ub() != infinity) | ||
{ | ||
const MPVariable* slack | ||
= problem->MakeNumVar(0, infinity, constraint->name() + "::up"); | ||
constraint->SetCoefficient(slack, -1.); | ||
slackVariables_.push_back(slack); | ||
} | ||
} | ||
} | ||
} | ||
|
||
void ConstraintSlackAnalysis::buildObjective(MPSolver* problem) const | ||
{ | ||
MPObjective* objective = problem->MutableObjective(); | ||
// Reset objective function | ||
objective->Clear(); | ||
// Only slack variables have a non-zero cost | ||
for (const MPVariable* slack : slackVariables_) | ||
{ | ||
objective->SetCoefficient(slack, 1.); | ||
} | ||
objective->SetMinimization(); | ||
} | ||
|
||
void ConstraintSlackAnalysis::printReport() const | ||
{ | ||
InfeasibleProblemReport report(slackVariables_); | ||
report.prettyPrint(); | ||
} | ||
|
||
} // namespace Antares::Optimization |
30 changes: 30 additions & 0 deletions
30
src/solver/infeasible-problem-analysis/constraint-slack-analysis.h
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,30 @@ | ||
#pragma once | ||
|
||
#include "unfeasibility-analysis.h" | ||
|
||
namespace Antares::Optimization | ||
{ | ||
|
||
/*! | ||
* That particular analysis relaxes all constraints by | ||
* adding slack variables for each one. | ||
*/ | ||
class ConstraintSlackAnalysis : public UnfeasibilityAnalysis | ||
{ | ||
public: | ||
ConstraintSlackAnalysis() = default; | ||
~ConstraintSlackAnalysis() override = default; | ||
|
||
void run(operations_research::MPSolver* problem) override; | ||
void printReport() const override; | ||
std::string title() const override { return "Slack variables analysis"; } | ||
|
||
private: | ||
void buildObjective(operations_research::MPSolver* problem) const; | ||
void addSlackVariables(operations_research::MPSolver* problem); | ||
|
||
std::vector<const operations_research::MPVariable*> slackVariables_; | ||
const std::string constraint_name_pattern = "^AreaHydroLevel::|::hourly::|::daily::|::weekly::|^FictiveLoads::"; | ||
}; | ||
|
||
} // namespace Antares::Optimization |
This file was deleted.
Oops, something went wrong.
This file was deleted.
Oops, something went wrong.
This file was deleted.
Oops, something went wrong.
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.