71 __ileft(false), __imiddle(false), __iright(false), __lValue(0.),
126 expr.__lCoeffs =
nullptr;
127 expr.__mCoeffs =
nullptr;
128 expr.__rCoeffs =
nullptr;
184 if (
this == &rhs)
return *
this;
203 if (
this == &rhs)
return *
this;
220 template <
typename SCALAR >
233 "expr::operator+= (expr) : <= present on one side of expr");
237 __mCoeffs->getWithDefault(rhs, 0.) += 1.;
245 "expr::operator+= (rhs) : <= present " 246 "on one side of rhs and/or expr");
251 __mCoeffs->getWithDefault(elt.first, 0.) += elt.second;
261 "expr::operator+= (rhs) : <= present " 262 "on one side of rhs and/or expr");
274 for (
const auto& elt : *rhs.__mCoeffs)
275 __mCoeffs->getWithDefault(elt.first, 0.) += elt.second;
282 template <
typename T >
286 "expr::operator+= (expr) : <= present on one side of expr");
298 "expr::operator-= (rhs) : <= present in one of expr");
302 __mCoeffs->getWithDefault(rhs, 0.) -= 1.;
311 "expr::operator-= (rhs) : <= present in one of rhs and/or expr");
316 __mCoeffs->getWithDefault(elt.first, 0.) -= elt.second;
323 template <
typename T >
327 "expr::operator-= (rhs) : <= present in one of expr");
353 "LpExpr::setSide ( const LpCol & from " 354 ") : too many <= ; no free side");
360 "LpExpr::setSide ( const LpCol & from " 361 ") : too many <= ; no free side");
390 "LpExpr::setSide ( const LpCol & from ) " 391 ": too many <= ; no free side");
418 "LpExpr::setSide ( const LpCol & from ) " 419 ": too many <= ; no free side");
426 "LpExpr::setSide ( const LpCol & from ) " 427 ": too many <= ; no free side");
434 "LpExpr::setSide ( const LpCol & from " 435 ") : too many <= ; no free side");
442 "LpExpr::setSide ( const LpCol & from " 443 ") : too many <= ; no free side");
446 if (!from.__imiddle)
return;
451 if (!from.__ileft && !from.__iright) {
475 "LpExpr::setSide ( const LpCol & from ) " 476 ": too many <= ; no free side");
480 else if (from.__ileft && !from.__iright) {
507 "LpExpr::setSide ( const LpCol & from ) " 508 ": too many <= ; no free side");
512 else if (from.__ileft && from.__iright) {
515 "LpExpr::setSide ( const LpCol & from ) " 516 ": too many <= ; no free side");
518 *
this = std::move(from);
523 "LpExpr::setSide ( const LpCol & from " 524 ") : too many <= ; no free side");
527 template <
typename SCALAR >
540 "LpExpr::setSide ( const LpCol & from " 541 ") : too many <= ; no free side");
559 std::ostringstream s;
561 s << std::endl <<
"left side : " << std::endl;
565 s << elt.first.toString() <<
" " << elt.second <<
" | ";
567 s << std::endl <<
"middle side : " << std::endl;
571 s << elt.first.toString() <<
" " << elt.second <<
" | ";
573 s << std::endl <<
"right side : " << std::endl;
577 s << elt.first.toString() <<
" " << elt.second <<
" | ";
580 <<
"lvalue : " <<
__lValue << std::endl
581 <<
"mvalue : " <<
__mValue << std::endl
582 <<
"rvalue : " <<
__rValue << std::endl;
599 for (
const auto& col : cols) {
600 double col_coeff = 0.;
604 col_coeff = expr.
__lCoeffs->operator[](col);
606 __coeffs->getWithDefault(col, 0.) -= col_coeff;
613 for (
const auto& col : cols) {
614 double col_coeff = 0;
618 col_coeff = expr.
__mCoeffs->operator[](col);
620 __coeffs->getWithDefault(col, 0.) -= col_coeff;
627 <<
"is not a valid inequality; no <= detected");
632 <<
"is not a valid inequality; " 633 "no variable in inequality, " 636 GUM_CONSTRUCTOR(
LpRow);
642 if (expr.__ileft && !expr.__iright) {
645 for (
const auto& col : cols) {
646 double col_coeff = 0;
648 if (expr.__lCoeffs->exists(col))
649 col_coeff = expr.__lCoeffs->operator[](col);
651 __coeffs->getWithDefault(col, 0.) -= col_coeff;
654 __cste = expr.__mValue - expr.__lValue;
655 }
else if (expr.__iright && !expr.__ileft) {
658 for (
const auto& col : cols) {
659 double col_coeff = 0;
661 if (expr.__mCoeffs->exists(col))
662 col_coeff = expr.__mCoeffs->operator[](col);
664 __coeffs->getWithDefault(col, 0.) -= col_coeff;
667 __cste = expr.__rValue - expr.__mValue;
670 "expr : " << expr.toString()
671 <<
"is not a valid inequality; no <= detected");
675 "expr : " << expr.toString()
676 <<
"is not a valid inequality; " 677 "no variable in inequality, " 680 GUM_CONSTRUCTOR(
LpRow);
690 row.__coeffs =
nullptr;
698 GUM_DESTRUCTOR(
LpRow);
719 std::ostringstream s;
725 if (elt.second > 0) {
726 if (elt.second != 1) {
727 s <<
" +" << elt.second <<
"*" << elt.first.toString();
729 s <<
" +" << elt.first.toString();
732 if (elt.second < 0) {
733 if (elt.second != -1) {
734 s <<
" " << elt.second <<
"*" << elt.first.toString();
736 s <<
" -" << elt.first.toString();
749 template <
typename GUM_SCALAR >
751 __positivity =
false;
756 template <
typename GUM_SCALAR >
760 __positivity(from.__positivity), __sumIsOne(from.__sumIsOne) {
763 for (
unsigned int i = 0, end = from.
__rows.size(); i < end; i++)
769 template <
typename GUM_SCALAR >
777 template <
typename GUM_SCALAR >
779 for (
const auto row :
__rows)
785 template <
typename GUM_SCALAR >
789 for (
const auto& row :
__rows)
793 __rows.shrink_to_fit();
795 __rows.resize(from.
__rows.size());
797 for (
unsigned int i = 0, end = from.
__rows.size(); i < end; i++)
807 template <
typename GUM_SCALAR >
819 template <
typename T >
820 std::ostream& operator<<(std::ostream& out, const LpInterface< T >& lpi) {
821 out << lpi.toString();
825 template <
typename GUM_SCALAR >
834 template <
typename GUM_SCALAR >
839 "LpInterface::addCols ( cols ) : cols " 840 "needs must be equal or greater than 1 : " 843 for (
unsigned int i = 0; i < cols; i++) {
850 template <
typename GUM_SCALAR >
854 "addRow ( const LpExpr & expr ) : expr : " 855 << expr.
toString() <<
"is not an inequality.");
860 LpExpr lexpr(expr,
true,
true,
false);
861 LpExpr rexpr(expr,
false,
true,
true);
864 new LpRow(std::move(lexpr),
867 new LpRow(std::move(rexpr),
872 template <
typename GUM_SCALAR >
874 if (!expr.__ileft && !expr.__iright)
876 "addRow ( const LpExpr & expr ) : expr : " 877 << expr.toString() <<
"is not an inequality.");
879 if ((expr.__ileft && !expr.__iright) || (!expr.__ileft && expr.__iright)) {
882 LpExpr lexpr(std::move(expr),
true,
true,
false);
885 LpExpr rexpr(std::move(expr),
false,
false,
true);
894 new LpRow(std::move(lexpr),
897 new LpRow(std::move(rexpr),
902 template <
typename GUM_SCALAR >
906 for (
const auto& col :
__cols)
912 template <
typename GUM_SCALAR >
918 for (
const auto& col :
__cols)
921 addRow(1 <= std::move(expr) <= 1);
926 template <
typename GUM_SCALAR >
943 for (
const auto& col :
__cols) {
948 addRow(1 <= std::move(expr) <= 1);
954 template <
typename GUM_SCALAR >
960 std::vector< std::vector< GUM_SCALAR > > lrsMatrix;
962 for (
const auto& row :
__rows) {
963 std::vector< GUM_SCALAR > expandedRow(
__cols.size() + 1, 0);
965 expandedRow[0] = row->__cste;
967 for (
const auto& elt : *row->__coeffs)
968 expandedRow[elt.first.id() + 1] = elt.second;
970 lrsMatrix.push_back(expandedRow);
980 template <
typename GUM_SCALAR >
985 template <
typename GUM_SCALAR >
987 std::ostringstream s;
989 s << std::endl << std::endl <<
"Variables : " << std::endl;
991 for (
const auto& col :
__cols)
992 s <<
" " << col.toString();
996 for (
const auto& row :
__rows)
997 s << std::endl << row->toString();
999 s << std::endl << std::endl;
1004 template <
typename GUM_SCALAR >
1006 for (
const auto& row :
__rows)
1010 __rows.shrink_to_fit();
1022 template <
typename GUM_SCALAR >
1024 for (
const auto& row :
__rows)
1028 __rows.shrink_to_fit();
1042 template <
typename T2 >
1044 LpExpr expr = std::move(lhs);
1050 template <
typename T2 >
1058 template <
typename T1, forb
idden_type< T1, LpExpr > >
1060 LpExpr expr = std::move(rhs);
1067 template <
typename T1, forb
idden_type< T1, LpExpr > >
1075 template <
typename T2, forb
idden_type< T2, LpExpr > >
1084 template <
typename T1,
1096 template <
typename T2 >
1098 LpExpr expr = std::move(lhs);
1104 template <
typename T2 >
1112 template <
typename T1, forb
idden_type< T1, LpExpr > >
1115 expr += std::move(rhs);
1122 template <
typename T1, forb
idden_type< T1, LpExpr > >
1131 template <
typename T2, forb
idden_type< T2, LpExpr > >
1140 template <
typename T1,
1141 forbidden_type< T1, LpExpr >,
1152 template <
typename SCALAR >
1160 template <
typename SCALAR >
1165 template <
typename SCALAR >
1171 template <
typename T1,
typename T2 >
1174 expr.
__addSide(std::forward< T1 >(lhs));
1175 expr.
__addSide(std::forward< T2 >(rhs));
1180 template <
typename T2 >
1185 template <
typename T2 >
1190 template <
typename T1,
1197 template <
typename T1,
1198 forbidden_type< T1, LpExpr& >,
1205 template <
typename T2 >
1210 template <
typename T2 >
1215 template <
typename T1,
1216 forbidden_type< T1, LpExpr >,
1222 template <
typename T1,
1223 forbidden_type< T1, LpExpr >,
~LpRow()
Default destructor.
bool __ileft
True if this expression has a non-empty left side L : L <= M <= R .
std::vector< std::vector< GUM_SCALAR > > solve()
Solve the linear program (H-representation of the polytope) by enumeration (of the polytope vertices)...
HashTable< LpCol, double > * __coeffs
The coefficients of the variables of the linear inequality.
void addProba()
Add positivity constraints and sum of variables is 1 ( probability constraints )
static LpExpr lessThan(T1 &&lhs, T2 &&rhs)
std::string toString() const
Get the string representation of a calling variable.
bool operator==(const LpCol &col) const
Test of equality == between two variables.
void fillMatrix(const std::vector< std::vector< GUM_SCALAR > > &matrix)
Fill the H-representation from the matrix given in argument.
double __cste
The constant of the linear inequality.
bool __iright
True if this expression has a non-empty right side R : L <= M <= R .
HashTable< LpCol, double > * __mCoeffs
The coefficients of each variable on the middle side L : L <= M <= R.
friend std::ostream & operator<<(std::ostream &out, const LpRow &row)
Overload of << to use with output streams ( such as std::cout << ).
void addRow(const LpExpr &expr)
Add rows to the linear program according to a given expression ( which must be at least an inequality...
void swap(HashTable< LpCol, double > *&a, HashTable< LpCol, double > *&b)
Swap the addresses of two pointers to hashTables.
LpCol(unsigned int id)
Default constructor.
Copyright 2005-2019 Pierre-Henri WUILLEMIN et Christophe GONZALES (LIP6) {prenom.nom}_at_lip6.fr.
LpExpr operator<=(const LpExpr &lhs, T2 &&rhs)
Overload of operator <= between anything and anything.
LpRow & operator=(const LpRow &row)
void __addSide(const LpCol &from)
Set the side of the calling expression, from LEFT TO RIGHT : L <= M <= R.
void addPositivity()
Add positivity constraints for all variables.
Copyright 2005-2019 Pierre-Henri WUILLEMIN et Christophe GONZALES (LIP6) {prenom.nom}_at_lip6.fr.
double __mValue
The constant on the middle side L : L <= M <= R.
void addSumIsOne()
Add sum of variables is 1 constraints.
The class for generic Hash Tables.
void clear()
Reset the rows (inequalities) and columns (variables) of the LP as if it was created.
Class representing a variable ( a column ) of a linear program, i.e.
LpInterface()
Default constructor, empty problem.
void clear()
Clear all data of the calling expression as if it was constructed.
Class template acting as a wrapper for Lexicographic Reverse Search by David Avis.
void setUpH(const Size &card)
Sets up an H-representation.
Class representing a linear expression.
LpExpr()
Default constructor.
double __rValue
The constant on the right side L : L <= M <= R.
Class representing a row of the linear program, i.e.
HashTable< LpCol, double > * __rCoeffs
The coefficients of each variable on the right side L : L <= M <= R.
LpExpr & operator-=(const LpCol &rhs)
Compound assignment operator -= with a variable.
std::ostream & operator<<(std::ostream &out, const LpCol &col)
std::string to_string(const Formula &f)
double __lValue
The constant on the left side L : L <= M <= R.
Class representing a linear program.
~LpCol()
Default destructor.
LpExpr operator+(LpExpr &&lhs, const T2 &rhs)
Overload of operator + between anything ( a scalar, a variable or an expression ) and anything except...
bool __sumIsOne
true if addSumIsOne() has been called, false otherwise.
unsigned int __id
Variable id.
bool __positivity
true if addPositivity() has been called, false otherwise.
LpExpr & operator=(const LpCol &rhs)
Assignment operator = with a variable.
LpRow(const LpExpr &expr, const std::vector< LpCol > &cols)
Constructor from an expression and the address of the vector of variables of the problem.
friend std::ostream & operator<<(std::ostream &out, const LpCol &col)
Overload of << to use with output streams ( such as std::cout << ).
HashTable< LpCol, double > * __lCoeffs
The coefficients of each variable on the left side L : L <= M <= R.
typename std::enable_if< !std::is_same< T1, T2 >::value, int >::type forbidden_type
Forbidden_type<T1,T2> return the "int" type if T1 and T2 are of the same type, else nothing...
void clearRows()
Reset the rows (inequalities) of the LP but not the columns (variables are kept). ...
std::vector< LpCol > getCols() const
Get the variables of the LP.
LpExpr operator*(const SCALAR &lhs, const LpCol &rhs)
Overload of operator * between a scalar and a variable.
std::vector< LpCol > addCols(const unsigned int &cols)
Insert new columns, i.e.
std::vector< LpRow *> __rows
Rows of the problem.
~LpInterface()
Default destructor.
void H2V()
H-representation to V-representation.
static LpExpr multiply(const SCALAR &lhs, const LpCol &rhs)
LpInterface< GUM_SCALAR > & operator=(const LpInterface< GUM_SCALAR > &from)
Copy compound assignment.
~LpExpr()
Default destructor.
LpCol addCol()
Insert a new column, i.e.
const matrix & getOutput() const
Get the output matrix solution of the problem.
std::string toString() const
Get the string representation of a calling expression.
std::string toString() const
Get the string representation of a calling linear program.
bool operator!=(const LpCol &col) const
Opposite of equality != test between two variables.
LpExpr & operator+=(const LpCol &rhs)
Compound assignment operator += with a variable.
LpCol & operator=(const LpCol &col)
Assignment operator = by copy.
LpExpr operator-(LpExpr &&lhs, const T2 &rhs)
Overload of operator - between anything ( a scalar, a variable or an expression ) and anything except...
std::vector< LpCol > __cols
Variables of the problem.
bool __imiddle
True if this expression has a non-empty middle side M ( the default ) : L <= M <= R ...
unsigned int id() const
Variable id accessor.
#define GUM_ERROR(type, msg)
bool operator<(const LpCol &col) const
Test of ordering < between two variables.
std::string toString() const
Get the string representation of a calling row.