src/lemon/lp_glpk.cc
author deba
Mon, 09 May 2005 11:24:26 +0000
changeset 1408 892c29484414
parent 1379 96a34c0904dd
child 1431 ad44b1dd8013
permissions -rw-r--r--
New graph reader interface.
     1 /* -*- C++ -*-
     2  * src/lemon/lp_glpk.cc - Part of LEMON, a generic C++ optimization library
     3  *
     4  * Copyright (C) 2005 Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
     5  * (Egervary Research Group on Combinatorial Optimization, EGRES).
     6  *
     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.
    10  *
    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
    13  * purpose.
    14  *
    15  */
    16 
    17 #ifndef LEMON_LP_GLPK_CC
    18 #define LEMON_LP_GLPK_CC
    19 
    20 ///\file
    21 ///\brief Implementation of the LEMON-GLPK lp solver interface.
    22 
    23 #include <lemon/lp_glpk.h>
    24 
    25 namespace lemon {
    26 
    27   ///\e
    28 
    29   ///\bug Unimplemented!
    30   ///
    31   LpSolverBase &LpGlpk::_newLp()
    32   {
    33     LpSolverBase *tmp=0;
    34     return *tmp;
    35   }
    36   
    37   ///\e
    38 
    39   ///\bug Unimplemented!
    40   ///
    41   LpSolverBase &LpGlpk::_copyLp()
    42   {
    43     LpSolverBase *tmp=0;
    44     return *tmp;
    45   }
    46 
    47   LpGlpk::LpGlpk() : Parent(), 
    48 		     lp(lpx_create_prob()) {
    49     ///\todo constrol function for this:
    50     lpx_set_int_parm(lp, LPX_K_DUAL, 1);
    51     messageLevel(0);
    52   }
    53   
    54   LpGlpk::~LpGlpk() {
    55     lpx_delete_prob(lp);
    56   }
    57   
    58   int LpGlpk::_addCol() { 
    59     int i=lpx_add_cols(lp, 1);
    60     _setColLowerBound(i, -INF);
    61     _setColUpperBound(i, INF);
    62     return i;
    63   }
    64 
    65   int LpGlpk::_addRow() { 
    66     int i=lpx_add_rows(lp, 1);
    67     return i;
    68   }
    69 
    70   
    71   void LpGlpk::_setRowCoeffs(int i, 
    72 			     int length,
    73 			     const int   * indices, 
    74 			     const Value   * values )
    75   {
    76     lpx_set_mat_row(lp, i, length,
    77 		    const_cast<int * >(indices) ,
    78 		    const_cast<Value * >(values));
    79   }
    80   
    81   void LpGlpk::_setColCoeffs(int i, 
    82 			     int length,
    83 			     const int   * indices, 
    84 			     const Value   * values)
    85   {
    86     lpx_set_mat_col(lp, i, length,
    87 		    const_cast<int * >(indices),
    88 		    const_cast<Value * >(values));
    89   }
    90   
    91   void LpGlpk::_setColLowerBound(int i, Value lo)
    92   {
    93     if (lo==INF) {
    94       //FIXME error
    95     }
    96     int b=lpx_get_col_type(lp, i);
    97     double up=lpx_get_col_ub(lp, i);	
    98     if (lo==-INF) {
    99       switch (b) {
   100       case LPX_FR:
   101       case LPX_LO:
   102 	lpx_set_col_bnds(lp, i, LPX_FR, lo, up);
   103 	break;
   104       case LPX_UP:
   105 	break;
   106       case LPX_DB:
   107       case LPX_FX:
   108 	lpx_set_col_bnds(lp, i, LPX_UP, lo, up);
   109 	break;
   110       default: ;
   111 	//FIXME error
   112       }
   113     } else {
   114       switch (b) {
   115       case LPX_FR:
   116       case LPX_LO:
   117 	lpx_set_col_bnds(lp, i, LPX_LO, lo, up);
   118 	break;
   119       case LPX_UP:	  
   120       case LPX_DB:
   121       case LPX_FX:
   122 	if (lo==up) 
   123 	  lpx_set_col_bnds(lp, i, LPX_FX, lo, up);
   124 	else 
   125 	  lpx_set_col_bnds(lp, i, LPX_DB, lo, up);
   126 	break;
   127       default: ;
   128 	//FIXME error
   129       }
   130     }
   131 
   132   }
   133   
   134   void LpGlpk::_setColUpperBound(int i, Value up)
   135   {
   136     if (up==-INF) {
   137       //FIXME error
   138     }
   139     int b=lpx_get_col_type(lp, i);
   140     double lo=lpx_get_col_lb(lp, i);
   141     if (up==INF) {
   142       switch (b) {
   143       case LPX_FR:
   144       case LPX_LO:
   145 	break;
   146       case LPX_UP:
   147 	lpx_set_col_bnds(lp, i, LPX_FR, lo, up);
   148 	break;
   149       case LPX_DB:
   150       case LPX_FX:
   151 	lpx_set_col_bnds(lp, i, LPX_LO, lo, up);
   152 	break;
   153       default: ;
   154 	//FIXME error
   155       }
   156     } else {
   157       switch (b) {
   158       case LPX_FR:
   159 	lpx_set_col_bnds(lp, i, LPX_UP, lo, up);
   160 	break;
   161       case LPX_UP:
   162 	lpx_set_col_bnds(lp, i, LPX_UP, lo, up);
   163 	break;
   164       case LPX_LO:
   165       case LPX_DB:
   166       case LPX_FX:
   167 	if (lo==up) 
   168 	  lpx_set_col_bnds(lp, i, LPX_FX, lo, up);
   169 	else 
   170 	  lpx_set_col_bnds(lp, i, LPX_DB, lo, up);
   171 	break;
   172       default: ;
   173 	//FIXME error
   174       }
   175     }
   176   }
   177   
   178 //   void LpGlpk::_setRowLowerBound(int i, Value lo)
   179 //   {
   180 //     if (lo==INF) {
   181 //       //FIXME error
   182 //     }
   183 //     int b=lpx_get_row_type(lp, i);
   184 //     double up=lpx_get_row_ub(lp, i);	
   185 //     if (lo==-INF) {
   186 //       switch (b) {
   187 //       case LPX_FR:
   188 //       case LPX_LO:
   189 // 	lpx_set_row_bnds(lp, i, LPX_FR, lo, up);
   190 // 	break;
   191 //       case LPX_UP:
   192 // 	break;
   193 //       case LPX_DB:
   194 //       case LPX_FX:
   195 // 	lpx_set_row_bnds(lp, i, LPX_UP, lo, up);
   196 // 	break;
   197 //       default: ;
   198 // 	//FIXME error
   199 //       }
   200 //     } else {
   201 //       switch (b) {
   202 //       case LPX_FR:
   203 //       case LPX_LO:
   204 // 	lpx_set_row_bnds(lp, i, LPX_LO, lo, up);
   205 // 	break;
   206 //       case LPX_UP:	  
   207 //       case LPX_DB:
   208 //       case LPX_FX:
   209 // 	if (lo==up) 
   210 // 	  lpx_set_row_bnds(lp, i, LPX_FX, lo, up);
   211 // 	else 
   212 // 	  lpx_set_row_bnds(lp, i, LPX_DB, lo, up);
   213 // 	break;
   214 //       default: ;
   215 // 	//FIXME error
   216 //       }
   217 //     }
   218 //   }
   219   
   220 //   void LpGlpk::_setRowUpperBound(int i, Value up)
   221 //   {
   222 //     if (up==-INF) {
   223 //       //FIXME error
   224 //     }
   225 //     int b=lpx_get_row_type(lp, i);
   226 //     double lo=lpx_get_row_lb(lp, i);
   227 //     if (up==INF) {
   228 //       switch (b) {
   229 //       case LPX_FR:
   230 //       case LPX_LO:
   231 // 	break;
   232 //       case LPX_UP:
   233 // 	lpx_set_row_bnds(lp, i, LPX_FR, lo, up);
   234 // 	break;
   235 //       case LPX_DB:
   236 //       case LPX_FX:
   237 // 	lpx_set_row_bnds(lp, i, LPX_LO, lo, up);
   238 // 	break;
   239 //       default: ;
   240 // 	//FIXME error
   241 //       }
   242 //     } else {
   243 //       switch (b) {
   244 //       case LPX_FR:
   245 // 	lpx_set_row_bnds(lp, i, LPX_UP, lo, up);
   246 // 	break;
   247 //       case LPX_UP:
   248 // 	lpx_set_row_bnds(lp, i, LPX_UP, lo, up);
   249 // 	break;
   250 //       case LPX_LO:
   251 //       case LPX_DB:
   252 //       case LPX_FX:
   253 // 	if (lo==up) 
   254 // 	  lpx_set_row_bnds(lp, i, LPX_FX, lo, up);
   255 // 	else 
   256 // 	  lpx_set_row_bnds(lp, i, LPX_DB, lo, up);
   257 // 	break;
   258 //       default: ;
   259 // 	//FIXME error
   260 //       }
   261 //     }
   262 //   }
   263 
   264   void LpGlpk::_setRowBounds(int i, Value lb, Value ub)
   265   {
   266     //Bad parameter
   267     if (lb==INF || ub==-INF) {
   268       //FIXME error
   269     }
   270 
   271     if (lb == -INF){
   272       if (ub == INF){
   273 	lpx_set_row_bnds(lp, i, LPX_FR, lb, ub);
   274       }
   275       else{
   276 	lpx_set_row_bnds(lp, i, LPX_UP, lb, ub);
   277       }
   278     }
   279     else{
   280       if (ub==INF){
   281 	lpx_set_row_bnds(lp, i, LPX_LO, lb, ub);
   282 
   283       }
   284       else{
   285 	if (lb == ub){
   286 	  lpx_set_row_bnds(lp, i, LPX_FX, lb, ub);
   287 	}
   288 	else{
   289 	  lpx_set_row_bnds(lp, i, LPX_DB, lb, ub);
   290 	}
   291       }
   292     }
   293 
   294   }
   295   
   296   void LpGlpk::_setObjCoeff(int i, Value obj_coef)
   297   {
   298     //i=0 means the constant term (shift)
   299     lpx_set_obj_coef(lp, i, obj_coef);
   300   }
   301 
   302   void LpGlpk::_clearObj()
   303   {
   304     for (int i=0;i<=lpx_get_num_cols(lp);++i){
   305       lpx_set_obj_coef(lp, i, 0);
   306     }
   307   }
   308 //   void LpGlpk::_setObj(int length,
   309 // 		       int  const * indices, 
   310 // 		       Value  const * values )
   311 //   {
   312 //     Value new_values[1+lpx_num_cols()];
   313 //     for (i=0;i<=lpx_num_cols();++i){
   314 //       new_values[i]=0;
   315 //     }
   316 //     for (i=1;i<=length;++i){
   317 //       new_values[indices[i]]=values[i];
   318 //     }
   319     
   320 //     for (i=0;i<=lpx_num_cols();++i){
   321 //       lpx_set_obj_coef(lp, i, new_values[i]);
   322 //     }
   323 //   }
   324 
   325   LpGlpk::SolveExitStatus LpGlpk::_solve()
   326   {
   327     int i=  lpx_simplex(lp);
   328     switch (i) {
   329     case LPX_E_OK: 
   330       return SOLVED;
   331       break;
   332     default:
   333       return UNSOLVED;
   334     }
   335   }
   336 
   337   LpGlpk::Value LpGlpk::_getPrimal(int i)
   338   {
   339     return lpx_get_col_prim(lp,i);
   340   }
   341   
   342   LpGlpk::Value LpGlpk::_getPrimalValue()
   343   {
   344     return lpx_get_obj_val(lp);
   345   }
   346   
   347  
   348   LpGlpk::SolutionStatus LpGlpk::_getPrimalStatus()
   349   {
   350     int stat=  lpx_get_status(lp);
   351     switch (stat) {
   352     case LPX_UNDEF://Undefined (no solve has been run yet)
   353       return UNDEFINED;
   354       break;
   355     case LPX_NOFEAS://There is no feasible solution (primal, I guess)
   356     case LPX_INFEAS://Infeasible 
   357       return INFEASIBLE;
   358       break;
   359     case LPX_UNBND://Unbounded
   360       return INFINITE;
   361       break;
   362     case LPX_FEAS://Feasible
   363       return FEASIBLE;
   364       break;
   365     case LPX_OPT://Feasible
   366       return OPTIMAL;
   367       break;
   368     default:
   369       return UNDEFINED; //to avoid gcc warning
   370       //FIXME error
   371     }
   372   }
   373 
   374 
   375   void LpGlpk::_setMax()
   376   {
   377     lpx_set_obj_dir(lp, LPX_MAX);
   378   }
   379 
   380   void LpGlpk::_setMin()
   381   {
   382     lpx_set_obj_dir(lp, LPX_MIN);
   383   }
   384 
   385  
   386   void LpGlpk::messageLevel(int m)
   387   {
   388     lpx_set_int_parm(lp, LPX_K_MSGLEV, m);
   389   }
   390 
   391   void LpGlpk::presolver(bool b)
   392   {
   393     lpx_set_int_parm(lp, LPX_K_PRESOL, b);
   394   }
   395 
   396  
   397 } //END OF NAMESPACE LEMON
   398 
   399 #endif //LEMON_LP_GLPK_CC