src/lemon/lp_glpk.cc
author alpar
Sun, 17 Apr 2005 18:57:22 +0000
changeset 1364 ee5959aa4410
parent 1359 1581f961cfaa
child 1368 f9d0d792c8a6
permissions -rw-r--r--
- compile failure fixed
- newLp(), copyLp() added
- more doc.
     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     return *((LpSolverBase *)0);
    34   }
    35   
    36   ///\e
    37 
    38   ///\bug Unimplemented!
    39   ///
    40   LpSolverBase &LpGlpk::_copyLp()
    41   {
    42     return *((LpSolverBase *)0);
    43   }
    44 
    45   LpGlpk::LpGlpk() : Parent(), 
    46 		     lp(lpx_create_prob()) {
    47     ///\todo constrol function for this:
    48     lpx_set_int_parm(lp, LPX_K_DUAL, 1);
    49     messageLevel(0);
    50   }
    51   
    52   LpGlpk::~LpGlpk() {
    53     lpx_delete_prob(lp);
    54   }
    55   
    56   int LpGlpk::_addCol() { 
    57     int i=lpx_add_cols(lp, 1);
    58     _setColLowerBound(i, -INF);
    59     _setColUpperBound(i, INF);
    60     return i;
    61   }
    62 
    63   int LpGlpk::_addRow() { 
    64     int i=lpx_add_rows(lp, 1);
    65     return i;
    66   }
    67 
    68   
    69   void LpGlpk::_setRowCoeffs(int i, 
    70 			     int length,
    71 			     const int   * indices, 
    72 			     const Value   * values )
    73   {
    74     lpx_set_mat_row(lp, i, length,
    75 		    const_cast<int * >(indices) ,
    76 		    const_cast<Value * >(values));
    77   }
    78   
    79   void LpGlpk::_setColCoeffs(int i, 
    80 			     int length,
    81 			     const int   * indices, 
    82 			     const Value   * values)
    83   {
    84     lpx_set_mat_col(lp, i, length,
    85 		    const_cast<int * >(indices),
    86 		    const_cast<Value * >(values));
    87   }
    88   
    89   void LpGlpk::_setColLowerBound(int i, Value lo)
    90   {
    91     if (lo==INF) {
    92       //FIXME error
    93     }
    94     int b=lpx_get_col_type(lp, i);
    95     double up=lpx_get_col_ub(lp, i);	
    96     if (lo==-INF) {
    97       switch (b) {
    98       case LPX_FR:
    99       case LPX_LO:
   100 	lpx_set_col_bnds(lp, i, LPX_FR, lo, up);
   101 	break;
   102       case LPX_UP:
   103 	break;
   104       case LPX_DB:
   105       case LPX_FX:
   106 	lpx_set_col_bnds(lp, i, LPX_UP, lo, up);
   107 	break;
   108       default: ;
   109 	//FIXME error
   110       }
   111     } else {
   112       switch (b) {
   113       case LPX_FR:
   114       case LPX_LO:
   115 	lpx_set_col_bnds(lp, i, LPX_LO, lo, up);
   116 	break;
   117       case LPX_UP:	  
   118       case LPX_DB:
   119       case LPX_FX:
   120 	if (lo==up) 
   121 	  lpx_set_col_bnds(lp, i, LPX_FX, lo, up);
   122 	else 
   123 	  lpx_set_col_bnds(lp, i, LPX_DB, lo, up);
   124 	break;
   125       default: ;
   126 	//FIXME error
   127       }
   128     }
   129 
   130   }
   131   
   132   void LpGlpk::_setColUpperBound(int i, Value up)
   133   {
   134     if (up==-INF) {
   135       //FIXME error
   136     }
   137     int b=lpx_get_col_type(lp, i);
   138     double lo=lpx_get_col_lb(lp, i);
   139     if (up==INF) {
   140       switch (b) {
   141       case LPX_FR:
   142       case LPX_LO:
   143 	break;
   144       case LPX_UP:
   145 	lpx_set_col_bnds(lp, i, LPX_FR, lo, up);
   146 	break;
   147       case LPX_DB:
   148       case LPX_FX:
   149 	lpx_set_col_bnds(lp, i, LPX_LO, lo, up);
   150 	break;
   151       default: ;
   152 	//FIXME error
   153       }
   154     } else {
   155       switch (b) {
   156       case LPX_FR:
   157 	lpx_set_col_bnds(lp, i, LPX_UP, lo, up);
   158 	break;
   159       case LPX_UP:
   160 	lpx_set_col_bnds(lp, i, LPX_UP, lo, up);
   161 	break;
   162       case LPX_LO:
   163       case LPX_DB:
   164       case LPX_FX:
   165 	if (lo==up) 
   166 	  lpx_set_col_bnds(lp, i, LPX_FX, lo, up);
   167 	else 
   168 	  lpx_set_col_bnds(lp, i, LPX_DB, lo, up);
   169 	break;
   170       default: ;
   171 	//FIXME error
   172       }
   173     }
   174   }
   175   
   176   void LpGlpk::_setRowLowerBound(int i, Value lo)
   177   {
   178     if (lo==INF) {
   179       //FIXME error
   180     }
   181     int b=lpx_get_row_type(lp, i);
   182     double up=lpx_get_row_ub(lp, i);	
   183     if (lo==-INF) {
   184       switch (b) {
   185       case LPX_FR:
   186       case LPX_LO:
   187 	lpx_set_row_bnds(lp, i, LPX_FR, lo, up);
   188 	break;
   189       case LPX_UP:
   190 	break;
   191       case LPX_DB:
   192       case LPX_FX:
   193 	lpx_set_row_bnds(lp, i, LPX_UP, lo, up);
   194 	break;
   195       default: ;
   196 	//FIXME error
   197       }
   198     } else {
   199       switch (b) {
   200       case LPX_FR:
   201       case LPX_LO:
   202 	lpx_set_row_bnds(lp, i, LPX_LO, lo, up);
   203 	break;
   204       case LPX_UP:	  
   205       case LPX_DB:
   206       case LPX_FX:
   207 	if (lo==up) 
   208 	  lpx_set_row_bnds(lp, i, LPX_FX, lo, up);
   209 	else 
   210 	  lpx_set_row_bnds(lp, i, LPX_DB, lo, up);
   211 	break;
   212       default: ;
   213 	//FIXME error
   214       }
   215     }
   216   }
   217   
   218   void LpGlpk::_setRowUpperBound(int i, Value up)
   219   {
   220     if (up==-INF) {
   221       //FIXME error
   222     }
   223     int b=lpx_get_row_type(lp, i);
   224     double lo=lpx_get_row_lb(lp, i);
   225     if (up==INF) {
   226       switch (b) {
   227       case LPX_FR:
   228       case LPX_LO:
   229 	break;
   230       case LPX_UP:
   231 	lpx_set_row_bnds(lp, i, LPX_FR, lo, up);
   232 	break;
   233       case LPX_DB:
   234       case LPX_FX:
   235 	lpx_set_row_bnds(lp, i, LPX_LO, lo, up);
   236 	break;
   237       default: ;
   238 	//FIXME error
   239       }
   240     } else {
   241       switch (b) {
   242       case LPX_FR:
   243 	lpx_set_row_bnds(lp, i, LPX_UP, lo, up);
   244 	break;
   245       case LPX_UP:
   246 	lpx_set_row_bnds(lp, i, LPX_UP, lo, up);
   247 	break;
   248       case LPX_LO:
   249       case LPX_DB:
   250       case LPX_FX:
   251 	if (lo==up) 
   252 	  lpx_set_row_bnds(lp, i, LPX_FX, lo, up);
   253 	else 
   254 	  lpx_set_row_bnds(lp, i, LPX_DB, lo, up);
   255 	break;
   256       default: ;
   257 	//FIXME error
   258       }
   259     }
   260   }
   261   
   262   void LpGlpk::_setObjCoeff(int i, Value obj_coef)
   263   {
   264     lpx_set_obj_coef(lp, i, obj_coef);
   265   }
   266 
   267 
   268   LpGlpk::SolveExitStatus LpGlpk::_solve()
   269   {
   270     int i=  lpx_simplex(lp);
   271     switch (i) {
   272     case LPX_E_OK: 
   273       return SOLVED;
   274       break;
   275     default:
   276       return UNSOLVED;
   277     }
   278   }
   279 
   280   LpGlpk::Value LpGlpk::_getPrimal(int i)
   281   {
   282     return lpx_get_col_prim(lp,i);
   283   }
   284   
   285   LpGlpk::Value LpGlpk::_getPrimalValue()
   286   {
   287     return lpx_get_obj_val(lp);
   288   }
   289   
   290  
   291   LpGlpk::SolutionStatus LpGlpk::_getPrimalStatus()
   292   {
   293     int stat=  lpx_get_status(lp);
   294     switch (stat) {
   295     case LPX_UNDEF://Undefined (no solve has been run yet)
   296       return UNDEFINED;
   297       break;
   298     case LPX_NOFEAS://There is no feasible solution (primal, I guess)
   299     case LPX_INFEAS://Infeasible 
   300       return INFEASIBLE;
   301       break;
   302     case LPX_UNBND://Unbounded
   303       return INFINITE;
   304       break;
   305     case LPX_FEAS://Feasible
   306       return FEASIBLE;
   307       break;
   308     case LPX_OPT://Feasible
   309       return OPTIMAL;
   310       break;
   311     default:
   312       return UNDEFINED; //to avoid gcc warning
   313       //FIXME error
   314     }
   315   }
   316 
   317 
   318   void LpGlpk::_setMax()
   319   {
   320     lpx_set_obj_dir(lp, LPX_MAX);
   321   }
   322 
   323   void LpGlpk::_setMin()
   324   {
   325     lpx_set_obj_dir(lp, LPX_MIN);
   326   }
   327 
   328  
   329   void LpGlpk::messageLevel(int m)
   330   {
   331     lpx_set_int_parm(lp, LPX_K_MSGLEV, m);
   332   }
   333 
   334   void LpGlpk::presolver(bool b)
   335   {
   336     lpx_set_int_parm(lp, LPX_K_PRESOL, b);
   337   }
   338 
   339  
   340 } //END OF NAMESPACE LEMON
   341 
   342 #endif //LEMON_LP_GLPK_CC