Several changes. \n If new map is added to mapstorage it emits signal with the name of the new map. This was important, because from now on not only tha mapwin should be updated. \n Furthermore algobox gets a pointer to mapstorage instead of only the mapnames from it. This is important because without it it would be complicated to pass all of the required maps to algobox.
2 * lemon/lp_base.h - Part of LEMON, a generic C++ optimization library
4 * Copyright (C) 2006 Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
5 * (Egervary Research Group on Combinatorial Optimization, EGRES).
7 * Permission to use, modify and distribute this software is granted
8 * provided that this copyright notice appears in all copies. For
9 * precise terms see the accompanying LICENSE file.
11 * This software is provided "AS IS" with no warranty of any kind,
12 * express or implied, and with no claim as to its suitability for any
17 #ifndef LEMON_LP_BASE_H
18 #define LEMON_LP_BASE_H
25 #include<lemon/utility.h>
26 #include<lemon/error.h>
27 #include<lemon/invalid.h>
30 ///\brief The interface of the LP solver interface.
31 ///\ingroup gen_opt_group
34 ///Internal data structure to convert floating id's to fix one's
36 ///\todo This might be implemented to be also usable in other places.
40 std::vector<int> index;
41 std::vector<int> cross;
44 _FixId() : first_free(-1) {};
45 ///Convert a floating id to a fix one
47 ///\param n is a floating id
48 ///\return the corresponding fix id
49 int fixId(int n) const {return cross[n];}
50 ///Convert a fix id to a floating one
52 ///\param n is a fix id
53 ///\return the corresponding floating id
54 int floatingId(int n) const { return index[n];}
55 ///Add a new floating id.
57 ///\param n is a floating id
58 ///\return the fix id of the new value
59 ///\todo Multiple additions should also be handled.
62 if(n>=int(cross.size())) {
65 cross[n]=index.size();
70 int next=index[first_free];
76 ///\todo Create an own exception type.
77 else throw LogicError(); //floatingId-s must form a continuous range;
81 ///\param n is a fix id
88 for(int i=fl+1;i<int(cross.size());++i) {
94 ///An upper bound on the largest fix id.
96 ///\todo Do we need this?
98 std::size_t maxFixId() { return cross.size()-1; }
102 ///Common base class for LP solvers
104 ///\todo Much more docs
105 ///\ingroup gen_opt_group
110 ///Possible outcomes of an LP solving procedure
111 enum SolveExitStatus {
112 ///This means that the problem has been successfully solved: either
113 ///an optimal solution has been found or infeasibility/unboundedness
116 ///Any other case (including the case when some user specified limit has been exceeded)
121 enum SolutionStatus {
122 ///Feasible solution has'n been found (but may exist).
124 ///\todo NOTFOUND might be a better name.
127 ///The problem has no feasible solution
129 ///Feasible solution found
131 ///Optimal solution exists and found
133 ///The cost function is unbounded
135 ///\todo Give a feasible solution and an infinite ray (and the
136 ///corresponding bases)
140 ///\e The type of the investigated LP problem
142 ///Primal-dual feasible
143 PRIMAL_DUAL_FEASIBLE = 0,
144 ///Primal feasible dual infeasible
145 PRIMAL_FEASIBLE_DUAL_INFEASIBLE = 1,
146 ///Primal infeasible dual feasible
147 PRIMAL_INFEASIBLE_DUAL_FEASIBLE = 2,
148 ///Primal-dual infeasible
149 PRIMAL_DUAL_INFEASIBLE = 3,
150 ///Could not determine so far
154 ///The floating point type used by the solver
155 typedef double Value;
156 ///The infinity constant
157 static const Value INF;
158 ///The not a number constant
159 static const Value NaN;
161 ///Refer to a column of the LP.
163 ///This type is used to refer to a column of the LP.
165 ///Its value remains valid and correct even after the addition or erase of
168 ///\todo Document what can one do with a Col (INVALID, comparing,
169 ///it is similar to Node/Edge)
173 friend class LpSolverBase;
175 typedef Value ExprValue;
176 typedef True LpSolverCol;
178 Col(const Invalid&) : id(-1) {}
179 bool operator<(Col c) const {return id<c.id;}
180 bool operator==(Col c) const {return id==c.id;}
181 bool operator!=(Col c) const {return id==c.id;}
184 ///Refer to a row of the LP.
186 ///This type is used to refer to a row of the LP.
188 ///Its value remains valid and correct even after the addition or erase of
191 ///\todo Document what can one do with a Row (INVALID, comparing,
192 ///it is similar to Node/Edge)
196 friend class LpSolverBase;
198 typedef Value ExprValue;
199 typedef True LpSolverRow;
201 Row(const Invalid&) : id(-1) {}
203 bool operator<(Row c) const {return id<c.id;}
204 bool operator==(Row c) const {return id==c.id;}
205 bool operator!=(Row c) const {return id==c.id;}
208 ///Linear expression of variables and a constant component
210 ///This data structure strores a linear expression of the variables
211 ///(\ref Col "Col"s) and also has a constant component.
213 ///There are several ways to access and modify the contents of this
215 ///- Its it fully compatible with \c std::map<Col,double>, so for expamle
216 ///if \c e is an Expr and \c v and \c w are of type \ref Col, then you can
217 ///read and modify the coefficients like
224 ///or you can also iterate through its elements.
227 ///for(LpSolverBase::Expr::iterator i=e.begin();i!=e.end();++i)
230 ///(This code computes the sum of all coefficients).
231 ///- Numbers (<tt>double</tt>'s)
232 ///and variables (\ref Col "Col"s) directly convert to an
233 ///\ref Expr and the usual linear operations are defined so
236 ///2*v-3.12*(v-w/2)+2
237 ///v*2.1+(3*v+(v*12+w+6)*3)/2
239 ///are valid \ref Expr "Expr"essions.
240 ///The usual assignment operations are also defined.
243 ///e+=2*v-3.12*(v-w/2)+2;
247 ///- The constant member can be set and read by \ref constComp()
250 ///double c=e.constComp();
253 ///\note \ref clear() not only sets all coefficients to 0 but also
254 ///clears the constant components.
258 class Expr : public std::map<Col,Value>
261 typedef LpSolverBase::Col Key;
262 typedef LpSolverBase::Value Value;
265 typedef std::map<Col,Value> Base;
269 typedef True IsLinExpression;
271 Expr() : Base(), const_comp(0) { }
273 Expr(const Key &v) : const_comp(0) {
274 Base::insert(std::make_pair(v, 1));
277 Expr(const Value &v) : const_comp(v) {}
279 void set(const Key &v,const Value &c) {
280 Base::insert(std::make_pair(v, c));
283 Value &constComp() { return const_comp; }
285 const Value &constComp() const { return const_comp; }
287 ///Removes the components with zero coefficient.
289 for (Base::iterator i=Base::begin(); i!=Base::end();) {
292 if ((*i).second==0) Base::erase(i);
297 ///Removes the coefficients closer to zero than \c tolerance.
298 void simplify(double &tolerance) {
299 for (Base::iterator i=Base::begin(); i!=Base::end();) {
302 if (std::fabs((*i).second)<tolerance) Base::erase(i);
307 ///Sets all coefficients and the constant component to 0.
314 Expr &operator+=(const Expr &e) {
315 for (Base::const_iterator j=e.begin(); j!=e.end(); ++j)
316 (*this)[j->first]+=j->second;
317 const_comp+=e.const_comp;
321 Expr &operator-=(const Expr &e) {
322 for (Base::const_iterator j=e.begin(); j!=e.end(); ++j)
323 (*this)[j->first]-=j->second;
324 const_comp-=e.const_comp;
328 Expr &operator*=(const Value &c) {
329 for (Base::iterator j=Base::begin(); j!=Base::end(); ++j)
335 Expr &operator/=(const Value &c) {
336 for (Base::iterator j=Base::begin(); j!=Base::end(); ++j)
345 ///This data stucture represents a linear constraint in the LP.
346 ///Basically it is a linear expression with a lower or an upper bound
347 ///(or both). These parts of the constraint can be obtained by the member
348 ///functions \ref expr(), \ref lowerBound() and \ref upperBound(),
350 ///There are two ways to construct a constraint.
351 ///- You can set the linear expression and the bounds directly
352 /// by the functions above.
353 ///- The operators <tt>\<=</tt>, <tt>==</tt> and <tt>\>=</tt>
354 /// are defined between expressions, or even between constraints whenever
355 /// it makes sense. Therefore if \c e and \c f are linear expressions and
356 /// \c s and \c t are numbers, then the followings are valid expressions
357 /// and thus they can be used directly e.g. in \ref addRow() whenever
365 ///\warning The validity of a constraint is checked only at run time, so
366 ///e.g. \ref addRow(<tt>x[1]\<=x[2]<=5</tt>) will compile, but will throw a
367 ///\ref LogicError exception.
371 typedef LpSolverBase::Expr Expr;
372 typedef Expr::Key Key;
373 typedef Expr::Value Value;
375 // static const Value INF;
376 // static const Value NaN;
383 Constr() : _expr(), _lb(NaN), _ub(NaN) {}
385 Constr(Value lb,const Expr &e,Value ub) :
386 _expr(e), _lb(lb), _ub(ub) {}
388 Constr(const Expr &e,Value ub) :
389 _expr(e), _lb(NaN), _ub(ub) {}
391 Constr(Value lb,const Expr &e) :
392 _expr(e), _lb(lb), _ub(NaN) {}
394 Constr(const Expr &e) :
395 _expr(e), _lb(NaN), _ub(NaN) {}
403 ///Reference to the linear expression
404 Expr &expr() { return _expr; }
405 ///Cont reference to the linear expression
406 const Expr &expr() const { return _expr; }
407 ///Reference to the lower bound.
410 ///- \ref INF "INF": the constraint is lower unbounded.
411 ///- \ref NaN "NaN": lower bound has not been set.
412 ///- finite number: the lower bound
413 Value &lowerBound() { return _lb; }
414 ///The const version of \ref lowerBound()
415 const Value &lowerBound() const { return _lb; }
416 ///Reference to the upper bound.
419 ///- \ref INF "INF": the constraint is upper unbounded.
420 ///- \ref NaN "NaN": upper bound has not been set.
421 ///- finite number: the upper bound
422 Value &upperBound() { return _ub; }
423 ///The const version of \ref upperBound()
424 const Value &upperBound() const { return _ub; }
425 ///Is the constraint lower bounded?
426 bool lowerBounded() const {
430 ///Is the constraint upper bounded?
431 bool upperBounded() const {
437 ///Linear expression of rows
439 ///This data structure represents a column of the matrix,
440 ///thas is it strores a linear expression of the dual variables
441 ///(\ref Row "Row"s).
443 ///There are several ways to access and modify the contents of this
445 ///- Its it fully compatible with \c std::map<Row,double>, so for expamle
446 ///if \c e is an DualExpr and \c v
447 ///and \c w are of type \ref Row, then you can
448 ///read and modify the coefficients like
455 ///or you can also iterate through its elements.
458 ///for(LpSolverBase::DualExpr::iterator i=e.begin();i!=e.end();++i)
461 ///(This code computes the sum of all coefficients).
462 ///- Numbers (<tt>double</tt>'s)
463 ///and variables (\ref Row "Row"s) directly convert to an
464 ///\ref DualExpr and the usual linear operations are defined so
468 ///v*2.1+(3*v+(v*12+w)*3)/2
470 ///are valid \ref DualExpr "DualExpr"essions.
471 ///The usual assignment operations are also defined.
474 ///e+=2*v-3.12*(v-w/2);
481 class DualExpr : public std::map<Row,Value>
484 typedef LpSolverBase::Row Key;
485 typedef LpSolverBase::Value Value;
488 typedef std::map<Row,Value> Base;
491 typedef True IsLinExpression;
493 DualExpr() : Base() { }
495 DualExpr(const Key &v) {
496 Base::insert(std::make_pair(v, 1));
499 void set(const Key &v,const Value &c) {
500 Base::insert(std::make_pair(v, c));
503 ///Removes the components with zero coefficient.
505 for (Base::iterator i=Base::begin(); i!=Base::end();) {
508 if ((*i).second==0) Base::erase(i);
513 ///Removes the coefficients closer to zero than \c tolerance.
514 void simplify(double &tolerance) {
515 for (Base::iterator i=Base::begin(); i!=Base::end();) {
518 if (std::fabs((*i).second)<tolerance) Base::erase(i);
524 ///Sets all coefficients to 0.
530 DualExpr &operator+=(const DualExpr &e) {
531 for (Base::const_iterator j=e.begin(); j!=e.end(); ++j)
532 (*this)[j->first]+=j->second;
536 DualExpr &operator-=(const DualExpr &e) {
537 for (Base::const_iterator j=e.begin(); j!=e.end(); ++j)
538 (*this)[j->first]-=j->second;
542 DualExpr &operator*=(const Value &c) {
543 for (Base::iterator j=Base::begin(); j!=Base::end(); ++j)
548 DualExpr &operator/=(const Value &c) {
549 for (Base::iterator j=Base::begin(); j!=Base::end(); ++j)
560 //Abstract virtual functions
561 virtual LpSolverBase &_newLp() = 0;
562 virtual LpSolverBase &_copyLp(){
563 ///\todo This should be implemented here, too, when we have problem retrieving routines. It can be overriden.
566 LpSolverBase & newlp(_newLp());
568 //return *(LpSolverBase*)0;
571 virtual int _addCol() = 0;
572 virtual int _addRow() = 0;
573 virtual void _eraseCol(int col) = 0;
574 virtual void _eraseRow(int row) = 0;
575 virtual void _setRowCoeffs(int i,
578 Value const * values ) = 0;
579 virtual void _setColCoeffs(int i,
582 Value const * values ) = 0;
583 virtual void _setCoeff(int row, int col, Value value) = 0;
584 virtual void _setColLowerBound(int i, Value value) = 0;
585 virtual void _setColUpperBound(int i, Value value) = 0;
586 // virtual void _setRowLowerBound(int i, Value value) = 0;
587 // virtual void _setRowUpperBound(int i, Value value) = 0;
588 virtual void _setRowBounds(int i, Value lower, Value upper) = 0;
589 virtual void _setObjCoeff(int i, Value obj_coef) = 0;
590 virtual void _clearObj()=0;
591 // virtual void _setObj(int length,
592 // int const * indices,
593 // Value const * values ) = 0;
594 virtual SolveExitStatus _solve() = 0;
595 virtual Value _getPrimal(int i) = 0;
596 virtual Value _getDual(int i) = 0;
597 virtual Value _getPrimalValue() = 0;
598 virtual bool _isBasicCol(int i) = 0;
599 virtual SolutionStatus _getPrimalStatus() = 0;
600 virtual SolutionStatus _getDualStatus() = 0;
601 ///\todo This could be implemented here, too, using _getPrimalStatus() and
603 virtual ProblemTypes _getProblemType() = 0;
605 virtual void _setMax() = 0;
606 virtual void _setMin() = 0;
608 //Own protected stuff
610 //Constant component of the objective function
611 Value obj_const_comp;
619 LpSolverBase() : obj_const_comp(0) {}
622 virtual ~LpSolverBase() {}
624 ///Creates a new LP problem
625 LpSolverBase &newLp() {return _newLp();}
626 ///Makes a copy of the LP problem
627 LpSolverBase ©Lp() {return _copyLp();}
629 ///\name Build up and modify the LP
633 ///Add a new empty column (i.e a new variable) to the LP
634 Col addCol() { Col c; c.id=cols.insert(_addCol()); return c;}
636 ///\brief Adds several new columns
637 ///(i.e a variables) at once
639 ///This magic function takes a container as its argument
640 ///and fills its elements
641 ///with new columns (i.e. variables)
643 ///- a standard STL compatible iterable container with
644 ///\ref Col as its \c values_type
647 ///std::vector<LpSolverBase::Col>
648 ///std::list<LpSolverBase::Col>
650 ///- a standard STL compatible iterable container with
651 ///\ref Col as its \c mapped_type
654 ///std::map<AnyType,LpSolverBase::Col>
656 ///- an iterable lemon \ref concept::WriteMap "write map" like
658 ///ListGraph::NodeMap<LpSolverBase::Col>
659 ///ListGraph::EdgeMap<LpSolverBase::Col>
661 ///\return The number of the created column.
664 int addColSet(T &t) { return 0;}
667 typename enable_if<typename T::value_type::LpSolverCol,int>::type
668 addColSet(T &t,dummy<0> = 0) {
670 for(typename T::iterator i=t.begin();i!=t.end();++i) {*i=addCol();s++;}
674 typename enable_if<typename T::value_type::second_type::LpSolverCol,
676 addColSet(T &t,dummy<1> = 1) {
678 for(typename T::iterator i=t.begin();i!=t.end();++i) {
685 typename enable_if<typename T::MapIt::Value::LpSolverCol,
687 addColSet(T &t,dummy<2> = 2) {
689 for(typename T::MapIt i(t); i!=INVALID; ++i)
698 ///Set a column (i.e a dual constraint) of the LP
700 ///\param c is the column to be modified
701 ///\param e is a dual linear expression (see \ref DualExpr)
702 ///\bug This is a temporary function. The interface will change to
704 void setCol(Col c,const DualExpr &e) {
705 std::vector<int> indices;
706 std::vector<Value> values;
707 indices.push_back(0);
709 for(DualExpr::const_iterator i=e.begin(); i!=e.end(); ++i)
710 if((*i).second!=0) { ///\bug EPSILON would be necessary here!!!
711 indices.push_back(rows.floatingId((*i).first.id));
712 values.push_back((*i).second);
714 _setColCoeffs(cols.floatingId(c.id),indices.size()-1,
715 &indices[0],&values[0]);
718 ///Add a new column to the LP
720 ///\param e is a dual linear expression (see \ref DualExpr)
721 ///\param obj is the corresponding component of the objective
722 ///function. It is 0 by default.
723 ///\return The created column.
724 ///\bug This is a temportary function. The interface will change to
726 Col addCol(const DualExpr &e, Value obj=0) {
733 ///Add a new empty row (i.e a new constraint) to the LP
735 ///This function adds a new empty row (i.e a new constraint) to the LP.
736 ///\return The created row
737 Row addRow() { Row r; r.id=rows.insert(_addRow()); return r;}
739 ///\brief Add several new rows
740 ///(i.e a constraints) at once
742 ///This magic function takes a container as its argument
743 ///and fills its elements
744 ///with new row (i.e. variables)
746 ///- a standard STL compatible iterable container with
747 ///\ref Row as its \c values_type
750 ///std::vector<LpSolverBase::Row>
751 ///std::list<LpSolverBase::Row>
753 ///- a standard STL compatible iterable container with
754 ///\ref Row as its \c mapped_type
757 ///std::map<AnyType,LpSolverBase::Row>
759 ///- an iterable lemon \ref concept::WriteMap "write map" like
761 ///ListGraph::NodeMap<LpSolverBase::Row>
762 ///ListGraph::EdgeMap<LpSolverBase::Row>
764 ///\return The number of rows created.
767 int addRowSet(T &t) { return 0;}
770 typename enable_if<typename T::value_type::LpSolverRow,int>::type
771 addRowSet(T &t,dummy<0> = 0) {
773 for(typename T::iterator i=t.begin();i!=t.end();++i) {*i=addRow();s++;}
777 typename enable_if<typename T::value_type::second_type::LpSolverRow,
779 addRowSet(T &t,dummy<1> = 1) {
781 for(typename T::iterator i=t.begin();i!=t.end();++i) {
788 typename enable_if<typename T::MapIt::Value::LpSolverRow,
790 addRowSet(T &t,dummy<2> = 2) {
792 for(typename T::MapIt i(t); i!=INVALID; ++i)
801 ///Set a row (i.e a constraint) of the LP
803 ///\param r is the row to be modified
804 ///\param l is lower bound (-\ref INF means no bound)
805 ///\param e is a linear expression (see \ref Expr)
806 ///\param u is the upper bound (\ref INF means no bound)
807 ///\bug This is a temportary function. The interface will change to
809 ///\todo Option to control whether a constraint with a single variable is
811 void setRow(Row r, Value l,const Expr &e, Value u) {
812 std::vector<int> indices;
813 std::vector<Value> values;
814 indices.push_back(0);
816 for(Expr::const_iterator i=e.begin(); i!=e.end(); ++i)
817 if((*i).second!=0) { ///\bug EPSILON would be necessary here!!!
818 indices.push_back(cols.floatingId((*i).first.id));
819 values.push_back((*i).second);
821 _setRowCoeffs(rows.floatingId(r.id),indices.size()-1,
822 &indices[0],&values[0]);
823 // _setRowLowerBound(rows.floatingId(r.id),l-e.constComp());
824 // _setRowUpperBound(rows.floatingId(r.id),u-e.constComp());
825 _setRowBounds(rows.floatingId(r.id),l-e.constComp(),u-e.constComp());
828 ///Set a row (i.e a constraint) of the LP
830 ///\param r is the row to be modified
831 ///\param c is a linear expression (see \ref Constr)
832 void setRow(Row r, const Constr &c) {
834 c.lowerBounded()?c.lowerBound():-INF,
836 c.upperBounded()?c.upperBound():INF);
839 ///Add a new row (i.e a new constraint) to the LP
841 ///\param l is the lower bound (-\ref INF means no bound)
842 ///\param e is a linear expression (see \ref Expr)
843 ///\param u is the upper bound (\ref INF means no bound)
844 ///\return The created row.
845 ///\bug This is a temportary function. The interface will change to
847 Row addRow(Value l,const Expr &e, Value u) {
853 ///Add a new row (i.e a new constraint) to the LP
855 ///\param c is a linear expression (see \ref Constr)
856 ///\return The created row.
857 Row addRow(const Constr &c) {
862 ///Erase a coloumn (i.e a variable) from the LP
864 ///\param c is the coloumn to be deleted
865 ///\todo Please check this
866 void eraseCol(Col c) {
867 _eraseCol(cols.floatingId(c.id));
870 ///Erase a row (i.e a constraint) from the LP
872 ///\param r is the row to be deleted
873 ///\todo Please check this
874 void eraseRow(Row r) {
875 _eraseRow(rows.floatingId(r.id));
879 ///Set an element of the coefficient matrix of the LP
881 ///\param r is the row of the element to be modified
882 ///\param c is the coloumn of the element to be modified
883 ///\param val is the new value of the coefficient
884 void setCoeff(Row r, Col c, Value val){
885 _setCoeff(rows.floatingId(r.id),cols.floatingId(c.id), val);
888 /// Set the lower bound of a column (i.e a variable)
890 /// The upper bound of a variable (column) has to be given by an
891 /// extended number of type Value, i.e. a finite number of type
892 /// Value or -\ref INF.
893 void colLowerBound(Col c, Value value) {
894 _setColLowerBound(cols.floatingId(c.id),value);
896 /// Set the upper bound of a column (i.e a variable)
898 /// The upper bound of a variable (column) has to be given by an
899 /// extended number of type Value, i.e. a finite number of type
900 /// Value or \ref INF.
901 void colUpperBound(Col c, Value value) {
902 _setColUpperBound(cols.floatingId(c.id),value);
904 /// Set the lower and the upper bounds of a column (i.e a variable)
906 /// The lower and the upper bounds of
907 /// a variable (column) have to be given by an
908 /// extended number of type Value, i.e. a finite number of type
909 /// Value, -\ref INF or \ref INF.
910 void colBounds(Col c, Value lower, Value upper) {
911 _setColLowerBound(cols.floatingId(c.id),lower);
912 _setColUpperBound(cols.floatingId(c.id),upper);
915 // /// Set the lower bound of a row (i.e a constraint)
917 // /// The lower bound of a linear expression (row) has to be given by an
918 // /// extended number of type Value, i.e. a finite number of type
919 // /// Value or -\ref INF.
920 // void rowLowerBound(Row r, Value value) {
921 // _setRowLowerBound(rows.floatingId(r.id),value);
923 // /// Set the upper bound of a row (i.e a constraint)
925 // /// The upper bound of a linear expression (row) has to be given by an
926 // /// extended number of type Value, i.e. a finite number of type
927 // /// Value or \ref INF.
928 // void rowUpperBound(Row r, Value value) {
929 // _setRowUpperBound(rows.floatingId(r.id),value);
932 /// Set the lower and the upper bounds of a row (i.e a constraint)
934 /// The lower and the upper bounds of
935 /// a constraint (row) have to be given by an
936 /// extended number of type Value, i.e. a finite number of type
937 /// Value, -\ref INF or \ref INF.
938 void rowBounds(Row c, Value lower, Value upper) {
939 _setRowBounds(rows.floatingId(c.id),lower, upper);
940 // _setRowUpperBound(rows.floatingId(c.id),upper);
943 ///Set an element of the objective function
944 void objCoeff(Col c, Value v) {_setObjCoeff(cols.floatingId(c.id),v); };
945 ///Set the objective function
947 ///\param e is a linear expression of type \ref Expr.
948 void setObj(Expr e) {
950 for (Expr::iterator i=e.begin(); i!=e.end(); ++i)
951 objCoeff((*i).first,(*i).second);
952 obj_const_comp=e.constComp();
956 void max() { _setMax(); }
958 void min() { _setMin(); }
964 ///\name Solve the LP
968 ///\e Solve the LP problem at hand
970 ///\return The result of the optimization procedure. Possible values and their meanings can be found in the documentation of \ref SolveExitStatus.
972 ///\todo Which method is used to solve the problem
973 SolveExitStatus solve() { return _solve(); }
977 ///\name Obtain the solution
981 /// The status of the primal problem (the original LP problem)
982 SolutionStatus primalStatus() {
983 return _getPrimalStatus();
986 /// The status of the dual (of the original LP) problem
987 SolutionStatus dualStatus() {
988 return _getDualStatus();
991 ///The type of the original LP problem
992 ProblemTypes problemType() {
993 return _getProblemType();
997 Value primal(Col c) { return _getPrimal(cols.floatingId(c.id)); }
1000 Value dual(Row r) { return _getDual(rows.floatingId(r.id)); }
1003 bool isBasicCol(Col c) { return _isBasicCol(cols.floatingId(c.id)); }
1008 ///- \ref INF or -\ref INF means either infeasibility or unboundedness
1009 /// of the primal problem, depending on whether we minimize or maximize.
1010 ///- \ref NaN if no primal solution is found.
1011 ///- The (finite) objective value if an optimal solution is found.
1012 Value primalValue() { return _getPrimalValue()+obj_const_comp;}
1019 ///\relates LpSolverBase::Expr
1021 inline LpSolverBase::Expr operator+(const LpSolverBase::Expr &a,
1022 const LpSolverBase::Expr &b)
1024 LpSolverBase::Expr tmp(a);
1030 ///\relates LpSolverBase::Expr
1032 inline LpSolverBase::Expr operator-(const LpSolverBase::Expr &a,
1033 const LpSolverBase::Expr &b)
1035 LpSolverBase::Expr tmp(a);
1041 ///\relates LpSolverBase::Expr
1043 inline LpSolverBase::Expr operator*(const LpSolverBase::Expr &a,
1044 const LpSolverBase::Value &b)
1046 LpSolverBase::Expr tmp(a);
1053 ///\relates LpSolverBase::Expr
1055 inline LpSolverBase::Expr operator*(const LpSolverBase::Value &a,
1056 const LpSolverBase::Expr &b)
1058 LpSolverBase::Expr tmp(b);
1064 ///\relates LpSolverBase::Expr
1066 inline LpSolverBase::Expr operator/(const LpSolverBase::Expr &a,
1067 const LpSolverBase::Value &b)
1069 LpSolverBase::Expr tmp(a);
1076 ///\relates LpSolverBase::Constr
1078 inline LpSolverBase::Constr operator<=(const LpSolverBase::Expr &e,
1079 const LpSolverBase::Expr &f)
1081 return LpSolverBase::Constr(-LpSolverBase::INF,e-f,0);
1086 ///\relates LpSolverBase::Constr
1088 inline LpSolverBase::Constr operator<=(const LpSolverBase::Value &e,
1089 const LpSolverBase::Expr &f)
1091 return LpSolverBase::Constr(e,f);
1096 ///\relates LpSolverBase::Constr
1098 inline LpSolverBase::Constr operator<=(const LpSolverBase::Expr &e,
1099 const LpSolverBase::Value &f)
1101 return LpSolverBase::Constr(e,f);
1106 ///\relates LpSolverBase::Constr
1108 inline LpSolverBase::Constr operator>=(const LpSolverBase::Expr &e,
1109 const LpSolverBase::Expr &f)
1111 return LpSolverBase::Constr(-LpSolverBase::INF,f-e,0);
1117 ///\relates LpSolverBase::Constr
1119 inline LpSolverBase::Constr operator>=(const LpSolverBase::Value &e,
1120 const LpSolverBase::Expr &f)
1122 return LpSolverBase::Constr(f,e);
1128 ///\relates LpSolverBase::Constr
1130 inline LpSolverBase::Constr operator>=(const LpSolverBase::Expr &e,
1131 const LpSolverBase::Value &f)
1133 return LpSolverBase::Constr(f,e);
1138 ///\relates LpSolverBase::Constr
1140 inline LpSolverBase::Constr operator==(const LpSolverBase::Expr &e,
1141 const LpSolverBase::Expr &f)
1143 return LpSolverBase::Constr(0,e-f,0);
1148 ///\relates LpSolverBase::Constr
1150 inline LpSolverBase::Constr operator<=(const LpSolverBase::Value &n,
1151 const LpSolverBase::Constr&c)
1153 LpSolverBase::Constr tmp(c);
1154 ///\todo Create an own exception type.
1155 if(!isnan(tmp.lowerBound())) throw LogicError();
1156 else tmp.lowerBound()=n;
1161 ///\relates LpSolverBase::Constr
1163 inline LpSolverBase::Constr operator<=(const LpSolverBase::Constr& c,
1164 const LpSolverBase::Value &n)
1166 LpSolverBase::Constr tmp(c);
1167 ///\todo Create an own exception type.
1168 if(!isnan(tmp.upperBound())) throw LogicError();
1169 else tmp.upperBound()=n;
1175 ///\relates LpSolverBase::Constr
1177 inline LpSolverBase::Constr operator>=(const LpSolverBase::Value &n,
1178 const LpSolverBase::Constr&c)
1180 LpSolverBase::Constr tmp(c);
1181 ///\todo Create an own exception type.
1182 if(!isnan(tmp.upperBound())) throw LogicError();
1183 else tmp.upperBound()=n;
1188 ///\relates LpSolverBase::Constr
1190 inline LpSolverBase::Constr operator>=(const LpSolverBase::Constr& c,
1191 const LpSolverBase::Value &n)
1193 LpSolverBase::Constr tmp(c);
1194 ///\todo Create an own exception type.
1195 if(!isnan(tmp.lowerBound())) throw LogicError();
1196 else tmp.lowerBound()=n;
1202 ///\relates LpSolverBase::DualExpr
1204 inline LpSolverBase::DualExpr operator+(const LpSolverBase::DualExpr &a,
1205 const LpSolverBase::DualExpr &b)
1207 LpSolverBase::DualExpr tmp(a);
1213 ///\relates LpSolverBase::DualExpr
1215 inline LpSolverBase::DualExpr operator-(const LpSolverBase::DualExpr &a,
1216 const LpSolverBase::DualExpr &b)
1218 LpSolverBase::DualExpr tmp(a);
1224 ///\relates LpSolverBase::DualExpr
1226 inline LpSolverBase::DualExpr operator*(const LpSolverBase::DualExpr &a,
1227 const LpSolverBase::Value &b)
1229 LpSolverBase::DualExpr tmp(a);
1236 ///\relates LpSolverBase::DualExpr
1238 inline LpSolverBase::DualExpr operator*(const LpSolverBase::Value &a,
1239 const LpSolverBase::DualExpr &b)
1241 LpSolverBase::DualExpr tmp(b);
1247 ///\relates LpSolverBase::DualExpr
1249 inline LpSolverBase::DualExpr operator/(const LpSolverBase::DualExpr &a,
1250 const LpSolverBase::Value &b)
1252 LpSolverBase::DualExpr tmp(a);
1260 #endif //LEMON_LP_BASE_H