src/lemon/lp_glpk.cc
author athos
Wed, 20 Apr 2005 15:06:42 +0000
changeset 1377 bfbb5b30c5b8
parent 1376 8de0c1aeeb32
child 1379 96a34c0904dd
permissions -rw-r--r--
_clearObj instead of _setObj.
     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::_setObjCoeff(int i, Value obj_coef)
   265   {
   266     //i=0 means the constant term (shift)
   267     lpx_set_obj_coef(lp, i, obj_coef);
   268   }
   269 
   270   void LpGlpk::_clearObj()
   271   {
   272     for (int i=0;i<=lpx_get_num_cols(lp);++i){
   273       lpx_set_obj_coef(lp, i, 0);
   274     }
   275   }
   276 //   void LpGlpk::_setObj(int length,
   277 // 		       int  const * indices, 
   278 // 		       Value  const * values )
   279 //   {
   280 //     Value new_values[1+lpx_num_cols()];
   281 //     for (i=0;i<=lpx_num_cols();++i){
   282 //       new_values[i]=0;
   283 //     }
   284 //     for (i=1;i<=length;++i){
   285 //       new_values[indices[i]]=values[i];
   286 //     }
   287     
   288 //     for (i=0;i<=lpx_num_cols();++i){
   289 //       lpx_set_obj_coef(lp, i, new_values[i]);
   290 //     }
   291 //   }
   292 
   293   LpGlpk::SolveExitStatus LpGlpk::_solve()
   294   {
   295     int i=  lpx_simplex(lp);
   296     switch (i) {
   297     case LPX_E_OK: 
   298       return SOLVED;
   299       break;
   300     default:
   301       return UNSOLVED;
   302     }
   303   }
   304 
   305   LpGlpk::Value LpGlpk::_getPrimal(int i)
   306   {
   307     return lpx_get_col_prim(lp,i);
   308   }
   309   
   310   LpGlpk::Value LpGlpk::_getPrimalValue()
   311   {
   312     return lpx_get_obj_val(lp);
   313   }
   314   
   315  
   316   LpGlpk::SolutionStatus LpGlpk::_getPrimalStatus()
   317   {
   318     int stat=  lpx_get_status(lp);
   319     switch (stat) {
   320     case LPX_UNDEF://Undefined (no solve has been run yet)
   321       return UNDEFINED;
   322       break;
   323     case LPX_NOFEAS://There is no feasible solution (primal, I guess)
   324     case LPX_INFEAS://Infeasible 
   325       return INFEASIBLE;
   326       break;
   327     case LPX_UNBND://Unbounded
   328       return INFINITE;
   329       break;
   330     case LPX_FEAS://Feasible
   331       return FEASIBLE;
   332       break;
   333     case LPX_OPT://Feasible
   334       return OPTIMAL;
   335       break;
   336     default:
   337       return UNDEFINED; //to avoid gcc warning
   338       //FIXME error
   339     }
   340   }
   341 
   342 
   343   void LpGlpk::_setMax()
   344   {
   345     lpx_set_obj_dir(lp, LPX_MAX);
   346   }
   347 
   348   void LpGlpk::_setMin()
   349   {
   350     lpx_set_obj_dir(lp, LPX_MIN);
   351   }
   352 
   353  
   354   void LpGlpk::messageLevel(int m)
   355   {
   356     lpx_set_int_parm(lp, LPX_K_MSGLEV, m);
   357   }
   358 
   359   void LpGlpk::presolver(bool b)
   360   {
   361     lpx_set_int_parm(lp, LPX_K_PRESOL, b);
   362   }
   363 
   364  
   365 } //END OF NAMESPACE LEMON
   366 
   367 #endif //LEMON_LP_GLPK_CC