Query functions have been implemented for GLPK (CPLEX breaks at the moment, I guess): These functions include:
retrieving one element of the coeff. matrix
retrieving one element of the obj function
lower bd for a variable
upper bound for a variable
lower and upper bounds for a row (these can not be handled separately at the moment)
direction of the optimization (is_max() function)
1.1 --- a/lemon/lp_base.h Mon Dec 04 18:09:09 2006 +0000
1.2 +++ b/lemon/lp_base.h Thu Dec 07 16:10:54 2006 +0000
1.3 @@ -706,10 +706,14 @@
1.4 virtual Value _getCoeff(int row, int col) = 0;
1.5
1.6 virtual void _setColLowerBound(int i, Value value) = 0;
1.7 + virtual Value _getColLowerBound(int i) = 0;
1.8 virtual void _setColUpperBound(int i, Value value) = 0;
1.9 + virtual Value _getColUpperBound(int i) = 0;
1.10 // virtual void _setRowLowerBound(int i, Value value) = 0;
1.11 // virtual void _setRowUpperBound(int i, Value value) = 0;
1.12 virtual void _setRowBounds(int i, Value lower, Value upper) = 0;
1.13 + virtual void _getRowBounds(int i, Value &lower, Value &upper)=0;
1.14 +
1.15 virtual void _setObjCoeff(int i, Value obj_coef) = 0;
1.16 virtual Value _getObjCoeff(int i) = 0;
1.17 virtual void _clearObj()=0;
1.18 @@ -1024,6 +1028,15 @@
1.19 void colLowerBound(Col c, Value value) {
1.20 _setColLowerBound(_lpId(c),value);
1.21 }
1.22 +
1.23 + /// Get the lower bound of a column (i.e a variable)
1.24 +
1.25 + /// This function returns the lower bound for column (variable) \t c
1.26 + /// (this might be -\ref INF as well).
1.27 + ///\return The lower bound for coloumn \t c
1.28 + Value colLowerBound(Col c) {
1.29 + return _getColLowerBound(_lpId(c));
1.30 + }
1.31
1.32 ///\brief Set the lower bound of several columns
1.33 ///(i.e a variables) at once
1.34 @@ -1071,7 +1084,16 @@
1.35 _setColUpperBound(_lpId(c),value);
1.36 };
1.37
1.38 - ///\brief Set the lower bound of several columns
1.39 + /// Get the upper bound of a column (i.e a variable)
1.40 +
1.41 + /// This function returns the upper bound for column (variable) \t c
1.42 + /// (this might be \ref INF as well).
1.43 + ///\return The upper bound for coloumn \t c
1.44 + Value colUpperBound(Col c) {
1.45 + return _getColUpperBound(_lpId(c));
1.46 + }
1.47 +
1.48 + ///\brief Set the upper bound of several columns
1.49 ///(i.e a variables) at once
1.50 ///
1.51 ///This magic function takes a container as its argument
1.52 @@ -1176,15 +1198,30 @@
1.53
1.54 /// Set the lower and the upper bounds of a row (i.e a constraint)
1.55
1.56 - /// The lower and the upper bounds of
1.57 + /// The lower and the upper bound of
1.58 /// a constraint (row) have to be given by an
1.59 /// extended number of type Value, i.e. a finite number of type
1.60 - /// Value, -\ref INF or \ref INF.
1.61 + /// Value, -\ref INF or \ref INF. There is no separate function for the
1.62 + /// lower and the upper bound because that would have been hard to implement
1.63 + /// for CPLEX.
1.64 void rowBounds(Row c, Value lower, Value upper) {
1.65 _setRowBounds(_lpId(c),lower, upper);
1.66 - // _setRowUpperBound(_lpId(c),upper);
1.67 }
1.68
1.69 + /// Get the lower and the upper bounds of a row (i.e a constraint)
1.70 +
1.71 + /// The lower and the upper bound of
1.72 + /// a constraint (row) are
1.73 + /// extended numbers of type Value, i.e. finite numbers of type
1.74 + /// Value, -\ref INF or \ref INF.
1.75 + /// \todo There is no separate function for the
1.76 + /// lower and the upper bound because we had problems with the
1.77 + /// implementation of the setting functions for CPLEX:
1.78 + /// check out whether this can be done for these functions.
1.79 + void getRowBounds(Row c, Value &lower, Value &upper) {
1.80 + _getRowBounds(_lpId(c),lower, upper);
1.81 + }
1.82 +
1.83 ///Set an element of the objective function
1.84 void objCoeff(Col c, Value v) {_setObjCoeff(_lpId(c),v); };
1.85
2.1 --- a/lemon/lp_cplex.cc Mon Dec 04 18:09:09 2006 +0000
2.2 +++ b/lemon/lp_cplex.cc Thu Dec 07 16:10:54 2006 +0000
2.3 @@ -43,6 +43,7 @@
2.4 }
2.5
2.6 LpSolverBase &LpCplex::_copyLp() {
2.7 + ///\bug FixID data is not copied!
2.8 //The first approach opens a new environment
2.9 LpCplex* newlp=new LpCplex();
2.10 //The routine CPXcloneprob can be used to create a new CPLEX problem
3.1 --- a/lemon/lp_glpk.cc Mon Dec 04 18:09:09 2006 +0000
3.2 +++ b/lemon/lp_glpk.cc Thu Dec 07 16:10:54 2006 +0000
3.3 @@ -213,10 +213,25 @@
3.4 }
3.5 }
3.6
3.7 - LpGlpk::Value LpGlpk::_getCoeff(int, int)
3.8 + LpGlpk::Value LpGlpk::_getCoeff(int row, int col)
3.9 {
3.10 - ///\todo This is not yet implemented!!!
3.11 +
3.12 + int length=lpx_get_mat_row(lp, row, 0, 0);
3.13 +
3.14 + std::vector<int> indices(length + 2);
3.15 + std::vector<Value> values(length + 2);
3.16 +
3.17 + lpx_get_mat_row(lp, row, &indices[0], &values[0]);
3.18 +
3.19 + //The following code does not suppose that the elements of the
3.20 + //array indices are sorted
3.21 + for (int i = 1; i <= length; ++i) {
3.22 + if (indices[i]==col){
3.23 + return values[i];
3.24 + }
3.25 + }
3.26 return 0;
3.27 +
3.28 }
3.29
3.30
3.31 @@ -262,6 +277,19 @@
3.32 }
3.33
3.34 }
3.35 +
3.36 + LpGlpk::Value LpGlpk::_getColLowerBound(int i)
3.37 + {
3.38 + int b=lpx_get_col_type(lp, i);
3.39 + switch (b) {
3.40 + case LPX_LO:
3.41 + case LPX_DB:
3.42 + case LPX_FX:
3.43 + return lpx_get_col_lb(lp, i);
3.44 + default: ;
3.45 + return -INF;
3.46 + }
3.47 + }
3.48
3.49 void LpGlpk::_setColUpperBound(int i, Value up)
3.50 {
3.51 @@ -306,6 +334,19 @@
3.52 }
3.53 }
3.54 }
3.55 +
3.56 + LpGlpk::Value LpGlpk::_getColUpperBound(int i)
3.57 + {
3.58 + int b=lpx_get_col_type(lp, i);
3.59 + switch (b) {
3.60 + case LPX_UP:
3.61 + case LPX_DB:
3.62 + case LPX_FX:
3.63 + return lpx_get_col_ub(lp, i);
3.64 + default: ;
3.65 + return INF;
3.66 + }
3.67 + }
3.68
3.69 // void LpGlpk::_setRowLowerBound(int i, Value lo)
3.70 // {
3.71 @@ -424,6 +465,30 @@
3.72 }
3.73
3.74 }
3.75 +
3.76 + void LpGlpk::_getRowBounds(int i, Value &lb, Value &ub)
3.77 + {
3.78 +
3.79 + int b=lpx_get_row_type(lp, i);
3.80 + switch (b) {
3.81 + case LPX_FR:
3.82 + case LPX_UP:
3.83 + lb = -INF;
3.84 + break;
3.85 + default:
3.86 + lb=lpx_get_row_lb(lp, i);
3.87 + }
3.88 +
3.89 + switch (b) {
3.90 + case LPX_FR:
3.91 + case LPX_LO:
3.92 + ub = INF;
3.93 + break;
3.94 + default:
3.95 + ub=lpx_get_row_ub(lp, i);
3.96 + }
3.97 +
3.98 + }
3.99
3.100 void LpGlpk::_setObjCoeff(int i, Value obj_coef)
3.101 {
4.1 --- a/lemon/lp_glpk.h Mon Dec 04 18:09:09 2006 +0000
4.2 +++ b/lemon/lp_glpk.h Thu Dec 07 16:10:54 2006 +0000
4.3 @@ -63,10 +63,14 @@
4.4 virtual Value _getCoeff(int row, int col);
4.5
4.6 virtual void _setColLowerBound(int i, Value value);
4.7 + virtual Value _getColLowerBound(int i);
4.8 virtual void _setColUpperBound(int i, Value value);
4.9 + virtual Value _getColUpperBound(int i);
4.10 +
4.11 // virtual void _setRowLowerBound(int i, Value value);
4.12 // virtual void _setRowUpperBound(int i, Value value);
4.13 virtual void _setRowBounds(int i, Value lower, Value upper);
4.14 + virtual void _getRowBounds(int i, Value &lb, Value &ub);
4.15 virtual void _setObjCoeff(int i, Value obj_coef);
4.16 virtual Value _getObjCoeff(int i);
4.17 virtual void _clearObj();
5.1 --- a/lemon/lp_skeleton.cc Mon Dec 04 18:09:09 2006 +0000
5.2 +++ b/lemon/lp_skeleton.cc Thu Dec 07 16:10:54 2006 +0000
5.3 @@ -78,9 +78,19 @@
5.4 {
5.5 }
5.6
5.7 + LpSkeleton::Value LpSkeleton::_getColLowerBound(int)
5.8 + {
5.9 + return 0;
5.10 + }
5.11 +
5.12 void LpSkeleton::_setColUpperBound(int, Value)
5.13 {
5.14 }
5.15 +
5.16 + LpSkeleton::Value LpSkeleton::_getColUpperBound(int)
5.17 + {
5.18 + return 0;
5.19 + }
5.20
5.21 // void LpSkeleton::_setRowLowerBound(int, Value)
5.22 // {
5.23 @@ -93,6 +103,10 @@
5.24 void LpSkeleton::_setRowBounds(int, Value, Value)
5.25 {
5.26 }
5.27 +
5.28 + void LpSkeleton::_getRowBounds(int, Value&, Value&)
5.29 + {
5.30 + }
5.31
5.32 void LpSkeleton::_setObjCoeff(int, Value)
5.33 {
6.1 --- a/lemon/lp_skeleton.h Mon Dec 04 18:09:09 2006 +0000
6.2 +++ b/lemon/lp_skeleton.h Thu Dec 07 16:10:54 2006 +0000
6.3 @@ -64,12 +64,22 @@
6.4 virtual void _setColLowerBound(int i, Value value);
6.5 /// \e
6.6
6.7 + /// The lower bound of a variable (column) is an
6.8 + /// extended number of type Value, i.e. a finite number of type
6.9 + /// Value or -\ref INF.
6.10 + virtual Value _getColLowerBound(int i);
6.11 +
6.12 /// The upper bound of a variable (column) have to be given by an
6.13 /// extended number of type Value, i.e. a finite number of type
6.14 /// Value or \ref INF.
6.15 virtual void _setColUpperBound(int i, Value value);
6.16 /// \e
6.17
6.18 + /// The upper bound of a variable (column) is an
6.19 + /// extended number of type Value, i.e. a finite number of type
6.20 + /// Value or \ref INF.
6.21 + virtual Value _getColUpperBound(int i);
6.22 +
6.23 // /// The lower bound of a linear expression (row) have to be given by an
6.24 // /// extended number of type Value, i.e. a finite number of type
6.25 // /// Value or -\ref INF.
6.26 @@ -89,6 +99,14 @@
6.27 /// \e
6.28
6.29
6.30 + /// The lower and the upper bound of
6.31 + /// a constraint (row) are
6.32 + /// extended numbers of type Value, i.e. finite numbers of type
6.33 + /// Value, -\ref INF or \ref INF.
6.34 + virtual void _getRowBounds(int i, Value &lb, Value &ub);
6.35 + /// \e
6.36 +
6.37 +
6.38 /// \e
6.39 virtual void _clearObj();
6.40 /// \e
7.1 --- a/test/lp_test.cc Mon Dec 04 18:09:09 2006 +0000
7.2 +++ b/test/lp_test.cc Thu Dec 07 16:10:54 2006 +0000
7.3 @@ -297,7 +297,14 @@
7.4 //Testing the problem retrieving routines
7.5 check(lp.objCoeff(x1)==1,"First term should be 1 in the obj function!");
7.6 check(lp.is_max(),"This is a maximization!");
7.7 - check(lp.coeff(upright,x1)==0,"The coefficient in question is 1!");
7.8 + check(lp.coeff(upright,x1)==1,"The coefficient in question is 1!");
7.9 + // std::cout<<lp.colLowerBound(x1)<<std::endl;
7.10 + check( lp.colLowerBound(x1)==0,"The lower bound for variable x1 should be 0.");
7.11 + check( lp.colUpperBound(x1)==LpSolverBase::INF,"The upper bound for variable x1 should be infty.");
7.12 + LpSolverBase::Value lb,ub;
7.13 + lp.getRowBounds(upright,lb,ub);
7.14 + check( lb==-LpSolverBase::INF,"The lower bound for the first row should be -infty.");
7.15 + check( ub==1,"The upper bound for the first row should be 1.");
7.16
7.17
7.18 //Maximization of x1+x2