Skip to content

Commit

Permalink
Implement solve() method for CPLEX.
Browse files Browse the repository at this point in the history
  • Loading branch information
sukritkalra committed Sep 27, 2023
1 parent 2c67dfe commit c00c0db
Show file tree
Hide file tree
Showing 11 changed files with 83 additions and 7 deletions.
2 changes: 1 addition & 1 deletion schedulers/tetrisched/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ endif()

if (EXISTS "${ORTOOLS_DIR}")
message("-- Adding Google OR-Tools : ${ORTOOLS_DIR}")
add_compile_definitions(_TETRISCHED_WITH_ORTOOLS_)
add_compile_definitions(_TETRISCHED_WITH_OR_TOOLS_)

set(ORTOOLS_LINK_LIBRARIES
"ortools")
Expand Down
6 changes: 6 additions & 0 deletions schedulers/tetrisched/include/tetrisched/CPLEXSolver.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,12 @@ class CPLEXSolver : public Solver {

/// Export the constructed model to the given file.
void exportModel(const std::string& fileName) override;

/// Solve the constructed model.
void solveModel() override;

/// Destroy the CPLEXSolver.
~CPLEXSolver();
};
} // namespace tetrisched
#endif // _TETRISCHED_CPLEX_SOLVER_HPP_
3 changes: 3 additions & 0 deletions schedulers/tetrisched/include/tetrisched/GoogleCPSolver.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,9 @@ class GoogleCPSolver : public Solver {

/// Export the constructed model to the given file.
void exportModel(const std::string& fileName) override;

/// Solve the constructed model.
void solveModel() override;
};
} // namespace tetrisched
#endif // _TETRISCHED_GOOGLE_CP_SOLVER_HPP_
4 changes: 3 additions & 1 deletion schedulers/tetrisched/include/tetrisched/GurobiSolver.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,9 @@ class GurobiSolver : public Solver {

/// Export the constructed model to the given file.
void exportModel(const std::string& fileName) override;

/// Solve the constructed model.
void solveModel() override;
};
} // namespace tetrisched
#endif // _TETRISCHED_GUROBI_SOLVER_HPP_

3 changes: 3 additions & 0 deletions schedulers/tetrisched/include/tetrisched/Solver.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,9 @@ class Solver {

/// Export the constructed model to the given file.
virtual void exportModel(const std::string& fileName) = 0;

/// Solve the constructed model.
virtual void solveModel() = 0;
};
} // namespace tetrisched
#endif // _TETRISCHED_SOLVER_HPP_
Expand Down
8 changes: 8 additions & 0 deletions schedulers/tetrisched/include/tetrisched/SolverModel.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,9 @@ class VariableT {
/// An optional upper-bound for the variable.
/// If unspecified, the solver will choose the upper bound for the given T.
std::optional<T> upperBound;
/// An optional solution value for the variable.
/// If unspecified, the solver has not found a solution for this problem yet.
std::optional<T> solutionValue;
/// Checks if the VariableType is valid.
/// Throws an exception if the VariableType is invalid.
/// Returns the type if it is valid.
Expand Down Expand Up @@ -78,6 +81,11 @@ class VariableT {
/// Retrieve the ID of this VariableT.
uint32_t getId() const;

/// Retrieve the solution value for this VariableT.
/// If the solution value is not set, then the solver hasn't found a solution
/// (yet).
std::optional<T> getValue() const;

/// Annotate friend classes for Solvers so that they have access to internals.
friend tetrisched::CPLEXSolver;
friend tetrisched::GurobiSolver;
Expand Down
32 changes: 32 additions & 0 deletions schedulers/tetrisched/src/CPLEXSolver.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -194,6 +194,38 @@ void CPLEXSolver::translateModel() {
void CPLEXSolver::exportModel(const std::string& fname) {
cplexInstance.exportModel(fname.c_str());
}

void CPLEXSolver::solveModel() {
cplexInstance.solve();

// Retrieve all the variables from the CPLEX model into the SolverModel.
for (const auto& [variableId, variable] : solverModel->variables) {
if (cplexVariables.find(variableId) == cplexVariables.end()) {
throw tetrisched::exceptions::SolverException(
"Variable " + variable->getName() + " not found in CPLEX model.");
}
switch (variable->variableType) {
case tetrisched::VariableType::VAR_INTEGER:
variable->solutionValue = cplexInstance.getValue(
std::get<IloIntVar>(cplexVariables.at(variableId)));
break;
case tetrisched::VariableType::VAR_CONTINUOUS:
variable->solutionValue = cplexInstance.getValue(
std::get<IloNumVar>(cplexVariables.at(variableId)));
break;
case tetrisched::VariableType::VAR_INDICATOR:
variable->solutionValue = cplexInstance.getValue(
std::get<IloBoolVar>(cplexVariables.at(variableId)));
break;
default:
throw tetrisched::exceptions::SolverException(
"Unsupported variable type: " + variable->variableType);
}
}
}

CPLEXSolver::~CPLEXSolver() { cplexEnv.end(); }

} // namespace tetrisched
// // Spend at least timeLimit sec. on optimization, but once
// // this limit is reached, quit as soon as the solution is acceptable
Expand Down
4 changes: 4 additions & 0 deletions schedulers/tetrisched/src/GoogleCPSolver.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -162,4 +162,8 @@ void GoogleCPSolver::exportModel(const std::string& fileName) {
cpModel->ExportToFile(fileName);
}

void GoogleCPSolver::solveModel() {
throw exceptions::SolverException("Not implemented yet!");
}

} // namespace tetrisched
5 changes: 4 additions & 1 deletion schedulers/tetrisched/src/GurobiSolver.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -133,5 +133,8 @@ void GurobiSolver::translateModel() {
void GurobiSolver::exportModel(const std::string& fileName) {
gurobiModel->write(fileName);
}
} // namespace tetrisched

void GurobiSolver::solveModel() {
throw exceptions::SolverException("Not implemented yet!");
}
} // namespace tetrisched
5 changes: 5 additions & 0 deletions schedulers/tetrisched/src/SolverModel.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,11 @@ uint32_t VariableT<T>::getId() const {
return variableId;
}

template <typename T>
std::optional<T> VariableT<T>::getValue() const {
return solutionValue;
}

/*
* Methods for Constraint.
* These methods provide an implementation of the Constraint class.
Expand Down
18 changes: 14 additions & 4 deletions schedulers/tetrisched/test/test_solver.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,9 @@
#ifdef _TETRISCHED_WITH_GUROBI_
#include "tetrisched/GurobiSolver.hpp"
#endif //_TETRISCHED_WITH_GUROBI_
// #ifdef _TETRISCHED_WITH_OR_TOOLS_
// #endif //_TETRISCHED_WITH_OR_TOOLS_
#ifdef _TETRISCHED_WITH_OR_TOOLS_
#include "tetrisched/GoogleCPSolver.hpp"
#endif //_TETRISCHED_WITH_OR_TOOLS_
#include "tetrisched/Solver.hpp"
#include "tetrisched/SolverModel.hpp"

Expand Down Expand Up @@ -50,7 +50,8 @@ TEST(SolverModelTypes, TestObjectiveFnConstruction) {
EXPECT_EQ(objectiveFn.size(), 1);
}

void constructModel(tetrisched::SolverModelPtr& solverModelPtr) {
tetrisched::VariablePtr constructModel(
tetrisched::SolverModelPtr& solverModelPtr) {
auto intVar = std::make_shared<tetrisched::Variable>(tetrisched::VAR_INTEGER,
"intVar", 0, 100);
solverModelPtr->addVariable(intVar);
Expand All @@ -63,6 +64,7 @@ void constructModel(tetrisched::SolverModelPtr& solverModelPtr) {
tetrisched::ObjectiveType::OBJ_MAXIMIZE);
objectiveFunction->addTerm(1, intVar);
solverModelPtr->setObjectiveFunction(std::move(objectiveFunction));
return intVar;
}

#ifdef _TETRISCHED_WITH_CPLEX_
Expand Down Expand Up @@ -94,7 +96,7 @@ TEST(SolverModelTypes, TestSolverModel) {
TEST(SolverModel, TestCPLEXSolverTranslation) {
tetrisched::CPLEXSolver cplexSolver;
auto solverModelPtr = cplexSolver.getModel();
constructModel(solverModelPtr);
auto intVar = constructModel(solverModelPtr);
solverModelPtr->exportModel("test_solvermodel.lp");
EXPECT_TRUE(std::filesystem::exists("test_solvermodel.lp"))
<< "The file test_solvermodel.lp was not created.";
Expand All @@ -104,6 +106,14 @@ TEST(SolverModel, TestCPLEXSolverTranslation) {
EXPECT_TRUE(std::filesystem::exists("test_cplexmodel.lp"))
<< "The file test_cplexmodel.lp was not created.";
std::filesystem::remove("test_cplexmodel.lp");

// Solve the model.
cplexSolver.solveModel();

// Check if solution is correct.
auto solutionValue = intVar->getValue();
EXPECT_TRUE(solutionValue.has_value()) << "No solution found.";
EXPECT_EQ(solutionValue.value(), 2) << "Solution is not correct.";
}
#endif //_TETRISCHED_WITH_CPLEX_

Expand Down

0 comments on commit c00c0db

Please sign in to comment.