243 |
248 |
244 bool operator< (Row c) const {return id< c.id;} |
249 bool operator< (Row c) const {return id< c.id;} |
245 bool operator> (Row c) const {return id> c.id;} |
250 bool operator> (Row c) const {return id> c.id;} |
246 bool operator==(Row c) const {return id==c.id;} |
251 bool operator==(Row c) const {return id==c.id;} |
247 bool operator!=(Row c) const {return id!=c.id;} |
252 bool operator!=(Row c) const {return id!=c.id;} |
248 }; |
253 }; |
|
254 |
|
255 static int id(const Row& row) { return row.id; } |
|
256 |
|
257 protected: |
|
258 |
|
259 int _lpId(const Col& col) const { |
|
260 return cols.floatingId(id(col)); |
|
261 } |
|
262 |
|
263 int _lpId(const Row& row) const { |
|
264 return rows.floatingId(id(row)); |
|
265 } |
|
266 |
|
267 |
|
268 public: |
249 |
269 |
250 ///Linear expression of variables and a constant component |
270 ///Linear expression of variables and a constant component |
251 |
271 |
252 ///This data structure strores a linear expression of the variables |
272 ///This data structure strores a linear expression of the variables |
253 ///(\ref Col "Col"s) and also has a constant component. |
273 ///(\ref Col "Col"s) and also has a constant component. |
594 return *this; |
618 return *this; |
595 } |
619 } |
596 }; |
620 }; |
597 |
621 |
598 |
622 |
|
623 private: |
|
624 |
|
625 template <typename _Base> |
|
626 class MappedIterator { |
|
627 public: |
|
628 |
|
629 typedef _Base Base; |
|
630 |
|
631 typedef typename Base::iterator_category iterator_category; |
|
632 typedef typename Base::difference_type difference_type; |
|
633 typedef const std::pair<int, Value> value_type; |
|
634 typedef value_type reference; |
|
635 class pointer { |
|
636 public: |
|
637 pointer(value_type& _value) : value(_value) {} |
|
638 value_type* operator->() { return &value; } |
|
639 private: |
|
640 value_type value; |
|
641 }; |
|
642 |
|
643 MappedIterator(const Base& _base, const LpSolverBase& _lp) |
|
644 : base(_base), lp(_lp) {} |
|
645 |
|
646 reference operator*() { |
|
647 return std::make_pair(lp._lpId(base->first), base->second); |
|
648 } |
|
649 |
|
650 pointer operator->() { |
|
651 return pointer(operator*()); |
|
652 } |
|
653 |
|
654 MappedIterator& operator++() { |
|
655 ++base; |
|
656 return *this; |
|
657 } |
|
658 |
|
659 MappedIterator& operator++(int) { |
|
660 MappedIterator tmp(*this); |
|
661 ++base; |
|
662 return tmp; |
|
663 } |
|
664 |
|
665 bool operator==(const MappedIterator& it) const { |
|
666 return base == it.base; |
|
667 } |
|
668 |
|
669 bool operator!=(const MappedIterator& it) const { |
|
670 return base != it.base; |
|
671 } |
|
672 |
|
673 private: |
|
674 Base base; |
|
675 const LpSolverBase& lp; |
|
676 }; |
|
677 |
599 protected: |
678 protected: |
|
679 |
|
680 /// STL compatible iterator for lp col |
|
681 typedef MappedIterator<Expr::const_iterator> LpRowIterator; |
|
682 /// STL compatible iterator for lp row |
|
683 typedef MappedIterator<DualExpr::const_iterator> LpColIterator; |
600 |
684 |
601 //Abstract virtual functions |
685 //Abstract virtual functions |
602 virtual LpSolverBase &_newLp() = 0; |
686 virtual LpSolverBase &_newLp() = 0; |
603 virtual LpSolverBase &_copyLp(){ |
687 virtual LpSolverBase &_copyLp(){ |
604 ///\todo This should be implemented here, too, when we have problem retrieving routines. It can be overriden. |
688 ///\todo This should be implemented here, too, when we have |
|
689 ///problem retrieving routines. It can be overriden. |
605 |
690 |
606 //Starting: |
691 //Starting: |
607 LpSolverBase & newlp(_newLp()); |
692 LpSolverBase & newlp(_newLp()); |
608 return newlp; |
693 return newlp; |
609 //return *(LpSolverBase*)0; |
694 //return *(LpSolverBase*)0; |
611 |
696 |
612 virtual int _addCol() = 0; |
697 virtual int _addCol() = 0; |
613 virtual int _addRow() = 0; |
698 virtual int _addRow() = 0; |
614 virtual void _eraseCol(int col) = 0; |
699 virtual void _eraseCol(int col) = 0; |
615 virtual void _eraseRow(int row) = 0; |
700 virtual void _eraseRow(int row) = 0; |
616 virtual void _getColName(int col, std::string & name) = 0; |
701 virtual void _getColName(int col, std::string & name) = 0; |
617 virtual void _setColName(int col, const std::string & name) = 0; |
702 virtual void _setColName(int col, const std::string & name) = 0; |
618 virtual void _setRowCoeffs(int i, |
703 virtual void _setRowCoeffs(int i, LpRowIterator b, LpRowIterator e) = 0; |
619 int length, |
704 virtual void _setColCoeffs(int i, LpColIterator b, LpColIterator e) = 0; |
620 int const * indices, |
|
621 Value const * values ) = 0; |
|
622 virtual void _setColCoeffs(int i, |
|
623 int length, |
|
624 int const * indices, |
|
625 Value const * values ) = 0; |
|
626 virtual void _setCoeff(int row, int col, Value value) = 0; |
705 virtual void _setCoeff(int row, int col, Value value) = 0; |
627 virtual void _setColLowerBound(int i, Value value) = 0; |
706 virtual void _setColLowerBound(int i, Value value) = 0; |
628 virtual void _setColUpperBound(int i, Value value) = 0; |
707 virtual void _setColUpperBound(int i, Value value) = 0; |
629 // virtual void _setRowLowerBound(int i, Value value) = 0; |
708 // virtual void _setRowLowerBound(int i, Value value) = 0; |
630 // virtual void _setRowUpperBound(int i, Value value) = 0; |
709 // virtual void _setRowUpperBound(int i, Value value) = 0; |
631 virtual void _setRowBounds(int i, Value lower, Value upper) = 0; |
710 virtual void _setRowBounds(int i, Value lower, Value upper) = 0; |
632 virtual void _setObjCoeff(int i, Value obj_coef) = 0; |
711 virtual void _setObjCoeff(int i, Value obj_coef) = 0; |
633 virtual void _clearObj()=0; |
712 virtual void _clearObj()=0; |
634 // virtual void _setObj(int length, |
713 |
635 // int const * indices, |
|
636 // Value const * values ) = 0; |
|
637 virtual SolveExitStatus _solve() = 0; |
714 virtual SolveExitStatus _solve() = 0; |
638 virtual Value _getPrimal(int i) = 0; |
715 virtual Value _getPrimal(int i) = 0; |
639 virtual Value _getDual(int i) = 0; |
716 virtual Value _getDual(int i) = 0; |
640 virtual Value _getPrimalValue() = 0; |
717 virtual Value _getPrimalValue() = 0; |
641 virtual bool _isBasicCol(int i) = 0; |
718 virtual bool _isBasicCol(int i) = 0; |
742 |
816 |
743 ///\param c is the column to be modified |
817 ///\param c is the column to be modified |
744 ///\param e is a dual linear expression (see \ref DualExpr) |
818 ///\param e is a dual linear expression (see \ref DualExpr) |
745 ///a better one. |
819 ///a better one. |
746 void col(Col c,const DualExpr &e) { |
820 void col(Col c,const DualExpr &e) { |
747 std::vector<int> indices; |
821 e.simplify(); |
748 std::vector<Value> values; |
822 _setColCoeffs(_lpId(c), LpColIterator(e.begin(), *this), |
749 indices.push_back(0); |
823 LpColIterator(e.end(), *this)); |
750 values.push_back(0); |
|
751 for(DualExpr::const_iterator i=e.begin(); i!=e.end(); ++i) |
|
752 if((*i).second!=0) { |
|
753 indices.push_back(rows.floatingId((*i).first.id)); |
|
754 values.push_back((*i).second); |
|
755 } |
|
756 _setColCoeffs(cols.floatingId(c.id),indices.size()-1, |
|
757 &indices[0],&values[0]); |
|
758 } |
824 } |
759 |
825 |
760 ///Add a new column to the LP |
826 ///Add a new column to the LP |
761 |
827 |
762 ///\param e is a dual linear expression (see \ref DualExpr) |
828 ///\param e is a dual linear expression (see \ref DualExpr) |
847 ///\bug This is a temportary function. The interface will change to |
913 ///\bug This is a temportary function. The interface will change to |
848 ///a better one. |
914 ///a better one. |
849 ///\todo Option to control whether a constraint with a single variable is |
915 ///\todo Option to control whether a constraint with a single variable is |
850 ///added or not. |
916 ///added or not. |
851 void row(Row r, Value l,const Expr &e, Value u) { |
917 void row(Row r, Value l,const Expr &e, Value u) { |
852 std::vector<int> indices; |
918 e.simplify(); |
853 std::vector<Value> values; |
919 _setRowCoeffs(_lpId(r), LpRowIterator(e.begin(), *this), |
854 indices.push_back(0); |
920 LpRowIterator(e.end(), *this)); |
855 values.push_back(0); |
921 // _setRowLowerBound(_lpId(r),l-e.constComp()); |
856 for(Expr::const_iterator i=e.begin(); i!=e.end(); ++i) |
922 // _setRowUpperBound(_lpId(r),u-e.constComp()); |
857 if((*i).second!=0) { ///\bug EPSILON would be necessary here!!! |
923 _setRowBounds(_lpId(r),l-e.constComp(),u-e.constComp()); |
858 indices.push_back(cols.floatingId((*i).first.id)); |
|
859 values.push_back((*i).second); |
|
860 } |
|
861 _setRowCoeffs(rows.floatingId(r.id),indices.size()-1, |
|
862 &indices[0],&values[0]); |
|
863 // _setRowLowerBound(rows.floatingId(r.id),l-e.constComp()); |
|
864 // _setRowUpperBound(rows.floatingId(r.id),u-e.constComp()); |
|
865 _setRowBounds(rows.floatingId(r.id),l-e.constComp(),u-e.constComp()); |
|
866 } |
924 } |
867 |
925 |
868 ///Set a row (i.e a constraint) of the LP |
926 ///Set a row (i.e a constraint) of the LP |
869 |
927 |
870 ///\param r is the row to be modified |
928 ///\param r is the row to be modified |
871 ///\param c is a linear expression (see \ref Constr) |
929 ///\param c is a linear expression (see \ref Constr) |
872 void row(Row r, const Constr &c) { |
930 void row(Row r, const Constr &c) { |
873 row(r, |
931 row(r, c.lowerBounded()?c.lowerBound():-INF, |
874 c.lowerBounded()?c.lowerBound():-INF, |
932 c.expr(), c.upperBounded()?c.upperBound():INF); |
875 c.expr(), |
|
876 c.upperBounded()?c.upperBound():INF); |
|
877 } |
933 } |
878 |
934 |
879 ///Add a new row (i.e a new constraint) to the LP |
935 ///Add a new row (i.e a new constraint) to the LP |
880 |
936 |
881 ///\param l is the lower bound (-\ref INF means no bound) |
937 ///\param l is the lower bound (-\ref INF means no bound) |
902 ///Erase a coloumn (i.e a variable) from the LP |
958 ///Erase a coloumn (i.e a variable) from the LP |
903 |
959 |
904 ///\param c is the coloumn to be deleted |
960 ///\param c is the coloumn to be deleted |
905 ///\todo Please check this |
961 ///\todo Please check this |
906 void eraseCol(Col c) { |
962 void eraseCol(Col c) { |
907 _eraseCol(cols.floatingId(c.id)); |
963 _eraseCol(_lpId(c)); |
908 cols.erase(c.id); |
964 cols.erase(c.id); |
909 } |
965 } |
910 ///Erase a row (i.e a constraint) from the LP |
966 ///Erase a row (i.e a constraint) from the LP |
911 |
967 |
912 ///\param r is the row to be deleted |
968 ///\param r is the row to be deleted |
913 ///\todo Please check this |
969 ///\todo Please check this |
914 void eraseRow(Row r) { |
970 void eraseRow(Row r) { |
915 _eraseRow(rows.floatingId(r.id)); |
971 _eraseRow(_lpId(r)); |
916 rows.erase(r.id); |
972 rows.erase(r.id); |
917 } |
973 } |
918 |
974 |
919 /// Get the name of a column |
975 /// Get the name of a column |
920 |
976 |
921 ///\param c is the coresponding coloumn |
977 ///\param c is the coresponding coloumn |
922 ///\return The name of the colunm |
978 ///\return The name of the colunm |
923 std::string colName(Col c){ |
979 std::string colName(Col c){ |
924 std::string name; |
980 std::string name; |
925 _getColName(cols.floatingId(c.id), name); |
981 _getColName(_lpId(c), name); |
926 return name; |
982 return name; |
927 } |
983 } |
928 |
984 |
929 /// Set the name of a column |
985 /// Set the name of a column |
930 |
986 |
931 ///\param c is the coresponding coloumn |
987 ///\param c is the coresponding coloumn |
932 ///\param name The name to be given |
988 ///\param name The name to be given |
933 void colName(Col c, const std::string & name){ |
989 void colName(Col c, const std::string& name){ |
934 _setColName(cols.floatingId(c.id), name); |
990 _setColName(_lpId(c), name); |
935 } |
991 } |
936 |
992 |
937 /// Set an element of the coefficient matrix of the LP |
993 /// Set an element of the coefficient matrix of the LP |
938 |
994 |
939 ///\param r is the row of the element to be modified |
995 ///\param r is the row of the element to be modified |
940 ///\param c is the coloumn of the element to be modified |
996 ///\param c is the coloumn of the element to be modified |
941 ///\param val is the new value of the coefficient |
997 ///\param val is the new value of the coefficient |
942 |
998 |
943 void coeff(Row r, Col c, Value val){ |
999 void coeff(Row r, Col c, Value val){ |
944 _setCoeff(rows.floatingId(r.id),cols.floatingId(c.id), val); |
1000 _setCoeff(_lpId(r),_lpId(c), val); |
945 } |
1001 } |
946 |
1002 |
947 /// Set the lower bound of a column (i.e a variable) |
1003 /// Set the lower bound of a column (i.e a variable) |
948 |
1004 |
949 /// The lower bound of a variable (column) has to be given by an |
1005 /// The lower bound of a variable (column) has to be given by an |
950 /// extended number of type Value, i.e. a finite number of type |
1006 /// extended number of type Value, i.e. a finite number of type |
951 /// Value or -\ref INF. |
1007 /// Value or -\ref INF. |
952 void colLowerBound(Col c, Value value) { |
1008 void colLowerBound(Col c, Value value) { |
953 _setColLowerBound(cols.floatingId(c.id),value); |
1009 _setColLowerBound(_lpId(c),value); |
954 } |
1010 } |
955 |
1011 |
956 ///\brief Set the lower bound of several columns |
1012 ///\brief Set the lower bound of several columns |
957 ///(i.e a variables) at once |
1013 ///(i.e a variables) at once |
958 /// |
1014 /// |
994 |
1050 |
995 /// The upper bound of a variable (column) has to be given by an |
1051 /// The upper bound of a variable (column) has to be given by an |
996 /// extended number of type Value, i.e. a finite number of type |
1052 /// extended number of type Value, i.e. a finite number of type |
997 /// Value or \ref INF. |
1053 /// Value or \ref INF. |
998 void colUpperBound(Col c, Value value) { |
1054 void colUpperBound(Col c, Value value) { |
999 _setColUpperBound(cols.floatingId(c.id),value); |
1055 _setColUpperBound(_lpId(c),value); |
1000 }; |
1056 }; |
1001 |
1057 |
1002 ///\brief Set the lower bound of several columns |
1058 ///\brief Set the lower bound of several columns |
1003 ///(i.e a variables) at once |
1059 ///(i.e a variables) at once |
1004 /// |
1060 /// |
1041 /// The lower and the upper bounds of |
1097 /// The lower and the upper bounds of |
1042 /// a variable (column) have to be given by an |
1098 /// a variable (column) have to be given by an |
1043 /// extended number of type Value, i.e. a finite number of type |
1099 /// extended number of type Value, i.e. a finite number of type |
1044 /// Value, -\ref INF or \ref INF. |
1100 /// Value, -\ref INF or \ref INF. |
1045 void colBounds(Col c, Value lower, Value upper) { |
1101 void colBounds(Col c, Value lower, Value upper) { |
1046 _setColLowerBound(cols.floatingId(c.id),lower); |
1102 _setColLowerBound(_lpId(c),lower); |
1047 _setColUpperBound(cols.floatingId(c.id),upper); |
1103 _setColUpperBound(_lpId(c),upper); |
1048 } |
1104 } |
1049 |
1105 |
1050 ///\brief Set the lower and the upper bound of several columns |
1106 ///\brief Set the lower and the upper bound of several columns |
1051 ///(i.e a variables) at once |
1107 ///(i.e a variables) at once |
1052 /// |
1108 /// |
1089 |
1145 |
1090 // /// The lower bound of a linear expression (row) has to be given by an |
1146 // /// The lower bound of a linear expression (row) has to be given by an |
1091 // /// extended number of type Value, i.e. a finite number of type |
1147 // /// extended number of type Value, i.e. a finite number of type |
1092 // /// Value or -\ref INF. |
1148 // /// Value or -\ref INF. |
1093 // void rowLowerBound(Row r, Value value) { |
1149 // void rowLowerBound(Row r, Value value) { |
1094 // _setRowLowerBound(rows.floatingId(r.id),value); |
1150 // _setRowLowerBound(_lpId(r),value); |
1095 // }; |
1151 // }; |
1096 // /// Set the upper bound of a row (i.e a constraint) |
1152 // /// Set the upper bound of a row (i.e a constraint) |
1097 |
1153 |
1098 // /// The upper bound of a linear expression (row) has to be given by an |
1154 // /// The upper bound of a linear expression (row) has to be given by an |
1099 // /// extended number of type Value, i.e. a finite number of type |
1155 // /// extended number of type Value, i.e. a finite number of type |
1100 // /// Value or \ref INF. |
1156 // /// Value or \ref INF. |
1101 // void rowUpperBound(Row r, Value value) { |
1157 // void rowUpperBound(Row r, Value value) { |
1102 // _setRowUpperBound(rows.floatingId(r.id),value); |
1158 // _setRowUpperBound(_lpId(r),value); |
1103 // }; |
1159 // }; |
1104 |
1160 |
1105 /// Set the lower and the upper bounds of a row (i.e a constraint) |
1161 /// Set the lower and the upper bounds of a row (i.e a constraint) |
1106 |
1162 |
1107 /// The lower and the upper bounds of |
1163 /// The lower and the upper bounds of |
1108 /// a constraint (row) have to be given by an |
1164 /// a constraint (row) have to be given by an |
1109 /// extended number of type Value, i.e. a finite number of type |
1165 /// extended number of type Value, i.e. a finite number of type |
1110 /// Value, -\ref INF or \ref INF. |
1166 /// Value, -\ref INF or \ref INF. |
1111 void rowBounds(Row c, Value lower, Value upper) { |
1167 void rowBounds(Row c, Value lower, Value upper) { |
1112 _setRowBounds(rows.floatingId(c.id),lower, upper); |
1168 _setRowBounds(_lpId(c),lower, upper); |
1113 // _setRowUpperBound(rows.floatingId(c.id),upper); |
1169 // _setRowUpperBound(_lpId(c),upper); |
1114 } |
1170 } |
1115 |
1171 |
1116 ///Set an element of the objective function |
1172 ///Set an element of the objective function |
1117 void objCoeff(Col c, Value v) {_setObjCoeff(cols.floatingId(c.id),v); }; |
1173 void objCoeff(Col c, Value v) {_setObjCoeff(_lpId(c),v); }; |
1118 ///Set the objective function |
1174 ///Set the objective function |
1119 |
1175 |
1120 ///\param e is a linear expression of type \ref Expr. |
1176 ///\param e is a linear expression of type \ref Expr. |
1121 ///\bug Is should be called obj() |
1177 ///\bug Is should be called obj() |
1122 void setObj(Expr e) { |
1178 void setObj(Expr e) { |
1211 |
1267 |
1212 ///Sets the type of the given coloumn to the given type |
1268 ///Sets the type of the given coloumn to the given type |
1213 /// |
1269 /// |
1214 ///Sets the type of the given coloumn to the given type. |
1270 ///Sets the type of the given coloumn to the given type. |
1215 void colType(Col c, ColTypes col_type) { |
1271 void colType(Col c, ColTypes col_type) { |
1216 _colType(cols.floatingId(c.id),col_type); |
1272 _colType(_lpId(c),col_type); |
1217 } |
1273 } |
1218 |
1274 |
1219 ///Gives back the type of the column. |
1275 ///Gives back the type of the column. |
1220 /// |
1276 /// |
1221 ///Gives back the type of the column. |
1277 ///Gives back the type of the column. |
1222 ColTypes colType(Col c){ |
1278 ColTypes colType(Col c){ |
1223 return _colType(cols.floatingId(c.id)); |
1279 return _colType(_lpId(c)); |
1224 } |
1280 } |
1225 |
1281 |
1226 ///Sets the type of the given Col to integer or remove that property. |
1282 ///Sets the type of the given Col to integer or remove that property. |
1227 /// |
1283 /// |
1228 ///Sets the type of the given Col to integer or remove that property. |
1284 ///Sets the type of the given Col to integer or remove that property. |
1438 ///\e |
1494 ///\e |
1439 |
1495 |
1440 ///\relates LpSolverBase::DualExpr |
1496 ///\relates LpSolverBase::DualExpr |
1441 /// |
1497 /// |
1442 inline LpSolverBase::DualExpr operator+(const LpSolverBase::DualExpr &a, |
1498 inline LpSolverBase::DualExpr operator+(const LpSolverBase::DualExpr &a, |
1443 const LpSolverBase::DualExpr &b) |
1499 const LpSolverBase::DualExpr &b) |
1444 { |
1500 { |
1445 LpSolverBase::DualExpr tmp(a); |
1501 LpSolverBase::DualExpr tmp(a); |
1446 tmp+=b; |
1502 tmp+=b; |
1447 return tmp; |
1503 return tmp; |
1448 } |
1504 } |
1449 ///\e |
1505 ///\e |
1450 |
1506 |
1451 ///\relates LpSolverBase::DualExpr |
1507 ///\relates LpSolverBase::DualExpr |
1452 /// |
1508 /// |
1453 inline LpSolverBase::DualExpr operator-(const LpSolverBase::DualExpr &a, |
1509 inline LpSolverBase::DualExpr operator-(const LpSolverBase::DualExpr &a, |
1454 const LpSolverBase::DualExpr &b) |
1510 const LpSolverBase::DualExpr &b) |
1455 { |
1511 { |
1456 LpSolverBase::DualExpr tmp(a); |
1512 LpSolverBase::DualExpr tmp(a); |
1457 tmp-=b; |
1513 tmp-=b; |
1458 return tmp; |
1514 return tmp; |
1459 } |
1515 } |
1460 ///\e |
1516 ///\e |
1461 |
1517 |
1462 ///\relates LpSolverBase::DualExpr |
1518 ///\relates LpSolverBase::DualExpr |
1463 /// |
1519 /// |
1464 inline LpSolverBase::DualExpr operator*(const LpSolverBase::DualExpr &a, |
1520 inline LpSolverBase::DualExpr operator*(const LpSolverBase::DualExpr &a, |
1465 const LpSolverBase::Value &b) |
1521 const LpSolverBase::Value &b) |
1466 { |
1522 { |
1467 LpSolverBase::DualExpr tmp(a); |
1523 LpSolverBase::DualExpr tmp(a); |
1468 tmp*=b; |
1524 tmp*=b; |
1469 return tmp; |
1525 return tmp; |
1470 } |
1526 } |
1472 ///\e |
1528 ///\e |
1473 |
1529 |
1474 ///\relates LpSolverBase::DualExpr |
1530 ///\relates LpSolverBase::DualExpr |
1475 /// |
1531 /// |
1476 inline LpSolverBase::DualExpr operator*(const LpSolverBase::Value &a, |
1532 inline LpSolverBase::DualExpr operator*(const LpSolverBase::Value &a, |
1477 const LpSolverBase::DualExpr &b) |
1533 const LpSolverBase::DualExpr &b) |
1478 { |
1534 { |
1479 LpSolverBase::DualExpr tmp(b); |
1535 LpSolverBase::DualExpr tmp(b); |
1480 tmp*=a; |
1536 tmp*=a; |
1481 return tmp; |
1537 return tmp; |
1482 } |
1538 } |
1483 ///\e |
1539 ///\e |
1484 |
1540 |
1485 ///\relates LpSolverBase::DualExpr |
1541 ///\relates LpSolverBase::DualExpr |
1486 /// |
1542 /// |
1487 inline LpSolverBase::DualExpr operator/(const LpSolverBase::DualExpr &a, |
1543 inline LpSolverBase::DualExpr operator/(const LpSolverBase::DualExpr &a, |
1488 const LpSolverBase::Value &b) |
1544 const LpSolverBase::Value &b) |
1489 { |
1545 { |
1490 LpSolverBase::DualExpr tmp(a); |
1546 LpSolverBase::DualExpr tmp(a); |
1491 tmp/=b; |
1547 tmp/=b; |
1492 return tmp; |
1548 return tmp; |
1493 } |
1549 } |