15 const Eigen::Matrix<Scalar,Eigen::Dynamic,Eigen::Dynamic>& C,
16 const Eigen::Matrix<Scalar,Eigen::Dynamic,1>& d,
17 const Scalar& small_number,
18 std::vector<VariableDomain>& domains,
19 std::string& halt_reason
23 auto zero = [&](
const Scalar& v) {
return -small_number < v && v < small_number; };
26 const unsigned int m = C.rows();
27 const unsigned int n = C.cols();
28 domains = std::vector<VariableDomain>(n);
31 for(
int row=0; row<m; row++) {
33 for(
int col=0; col<n; col++) {
34 if(!zero(C(row,col))) {
51 halt_reason =
"The constraint matrix has row " + std::to_string(row) +
" filled with zeros: the problem is degenerate.";
57 if(C(row,nzcol) < 0 && d(row) <= 0) {
59 EigenOpt_SIMPLEX_DBG(
"variable " << nzcol <<
" has a non-negative constraint (row " << row <<
")");
60 domains[nzcol].non_negative =
true;
61 domains[nzcol].idx = row;
63 if(C(row,nzcol) > 0 && d(row) <= 0) {
65 if(domains[nzcol].non_negative) {
66 halt_reason =
"Variable " + std::to_string(nzcol) +
" has both non-negativity constraint (row " + std::to_string(domains[nzcol].idx) +
") and non-positivity constraint (row " + std::to_string(row) +
").";
71 EigenOpt_SIMPLEX_DBG(
"variable " << nzcol <<
" has a non-positive constraint (row " << row <<
")");
72 domains[nzcol].non_positive =
true;
73 domains[nzcol].idx = row;
84 const std::vector<VariableDomain>& domains
91 const unsigned int n = domains.size();
99 for(
int i=0; i<n; i++) {
100 if(!domains[i].non_negative)
102 if(!domains[i].non_positive)
107 MatrixXs T = MatrixXs::Zero(n,nv);
110 unsigned int col = 0;
113 for(
int i=0; i<n; i++) {
114 if(!domains[i].non_positive) {
118 if(!domains[i].non_negative) {
123 eigen_assert(col==nv &&
"INTERNAL ERROR WHILE INITIALIZING THE TRANSFORMATION MATRIX T: THE FINAL COLUMN COUNT DOES NOT EQUAL THE NUMBER OF WORKING VARIABLES");
129template<
class Scalar>
131 const Eigen::Matrix<Scalar,Eigen::Dynamic,Eigen::Dynamic>& C,
132 const Eigen::Matrix<Scalar,Eigen::Dynamic,1>& d,
133 const Scalar& small_number,
134 Eigen::Matrix<Scalar, Eigen::Dynamic, Eigen::Dynamic>& T,
135 std::string& halt_reason
143 std::vector<VariableDomain> domains;
152template<
class Scalar>
154 Eigen::Matrix<Scalar,Eigen::Dynamic,Eigen::Dynamic>&
tableau,
174template<
class Scalar>
176 Eigen::Matrix<Scalar,Eigen::Dynamic,Eigen::Dynamic>&
tableau,
211 halt_reason =
"No positive coefficient found in the tableau for the entering variable: the problem is unbounded.";
233template<
class Scalar>
235 const Eigen::Matrix<Scalar, Eigen::Dynamic, Eigen::Dynamic>&
C,
236 const Eigen::Matrix<Scalar, Eigen::Dynamic, 1>&
d,
237 Eigen::Matrix<Scalar, Eigen::Dynamic, Eigen::Dynamic>&
tableau,
245 const unsigned int m =
C.rows();
246 const unsigned int n =
C.cols();
250 const unsigned int na = std::count_if(
d.data(),
d.data()+
m, [](
const Scalar&
x){return x<0;});
256 const unsigned int dcol =
n +
m +
na;
262 for(
int i=0;
i<
m;
i++) {
286template<
class Scalar>
288 Eigen::Matrix<Scalar, Eigen::Dynamic, Eigen::Dynamic>&
tableau,
301template<
class Scalar>
303 const Eigen::Matrix<Scalar, Eigen::Dynamic, 1>&
objective,
304 Eigen::Matrix<Scalar,Eigen::Dynamic,Eigen::Dynamic>&
tableau,
312 const unsigned int m =
tableau.rows() - 1;
323 for(
unsigned int i=0;
i<
m;
i++) {
346 for(
unsigned int i=0;
i<
m;
i++) {
354 for(
unsigned int i=0;
i<
m;
i++) {
363 for(
unsigned int j=0;
j<
nv+
m;
j++) {
374 halt_reason =
"After the first step, it was not possible to replace the artificial variable p" + std::to_string(
basic_variables[
i] -
nv -
m) +
" with another non-basic, non-artificial variable.";
394 tableau.bottomRightCorner(1,
m+1).setZero();
427template<
class Scalar>
429 const Eigen::Matrix<Scalar, Eigen::Dynamic, 1>&
objective,
430 Eigen::Matrix<Scalar,Eigen::Dynamic,Eigen::Dynamic>&
tableau,
439 const unsigned int m =
tableau.rows() - 1;
448 for(
unsigned int i=0;
i<
m;
i++) {
471 for(
unsigned int i=0;
i<
m;
i++) {
Eigen::Matrix< Scalar, Eigen::Dynamic, Eigen::Dynamic > transformation_matrix_from_domains(const std::vector< VariableDomain > &domains)
Calculate a transformation matrix so that , .
void pivot(Eigen::Matrix< Scalar, Eigen::Dynamic, Eigen::Dynamic > &tableau, int entering_variable, int leaving_variable)
Perform a pivot operation between a basic and a non-basic variable.
bool deduce_variables_domains(const Eigen::Matrix< Scalar, Eigen::Dynamic, Eigen::Dynamic > &C, const Eigen::Matrix< Scalar, Eigen::Dynamic, 1 > &d, const Scalar &small_number, std::vector< VariableDomain > &domains, std::string &halt_reason)
Given a set of inequality constraints, deduce the domain of the decision variables.
bool simplex(Eigen::Matrix< Scalar, Eigen::Dynamic, Eigen::Dynamic > &tableau, std::vector< int > &basic_variables, const Scalar &small_number, std::string &halt_reason)
Perform successive pivot operations until a termination condition is met.
bool transformation_matrix(const Eigen::Matrix< Scalar, Eigen::Dynamic, Eigen::Dynamic > &C, const Eigen::Matrix< Scalar, Eigen::Dynamic, 1 > &d, const Scalar &small_number, Eigen::Matrix< Scalar, Eigen::Dynamic, Eigen::Dynamic > &T, std::string &halt_reason)
Calculate a transformation matrix so that , .
void create_tableau(const Eigen::Matrix< Scalar, Eigen::Dynamic, Eigen::Dynamic > &C, const Eigen::Matrix< Scalar, Eigen::Dynamic, 1 > &d, Eigen::Matrix< Scalar, Eigen::Dynamic, Eigen::Dynamic > &tableau, std::vector< int > &basic_variables)
Create a Simplex Tableau given a set of inequality constraints.
bool two_steps_method(const Eigen::Matrix< Scalar, Eigen::Dynamic, 1 > &objective, Eigen::Matrix< Scalar, Eigen::Dynamic, Eigen::Dynamic > &tableau, std::vector< int > &basic_variables, unsigned int na, const Scalar &small_number, std::string &halt_reason)
Solve a minimization problem using the two-steps Simplex method.
bool penalty_method(const Eigen::Matrix< Scalar, Eigen::Dynamic, 1 > &objective, Eigen::Matrix< Scalar, Eigen::Dynamic, Eigen::Dynamic > &tableau, std::vector< int > &basic_variables, unsigned int na, const Scalar &small_number, const Scalar &large_number, std::string &halt_reason)
Solve a minimization problem using the penalty Simplex method.
void eliminate_objective(Eigen::Matrix< Scalar, Eigen::Dynamic, Eigen::Dynamic > &tableau, const std::vector< int > &basic_variables)
Use Gaussian elimination on the last row of the tableau.
Main namespace of this project, containing all utilities.
#define EigenOpt_SIMPLEX_DBG(x)
#define EigenOptTypedefs(ScalarType)