src/lemon/lp_glpk.cc
author ladanyi
Mon, 18 Apr 2005 17:29:11 +0000
changeset 1371 e1c99f5bdb3f
parent 1364 ee5959aa4410
child 1376 8de0c1aeeb32
permissions -rw-r--r--
ignore src/demo/lp_maxflow_demo
     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     lpx_set_obj_coef(lp, i, obj_coef);
   267   }
   268 
   269 
   270   LpGlpk::SolveExitStatus LpGlpk::_solve()
   271   {
   272     int i=  lpx_simplex(lp);
   273     switch (i) {
   274     case LPX_E_OK: 
   275       return SOLVED;
   276       break;
   277     default:
   278       return UNSOLVED;
   279     }
   280   }
   281 
   282   LpGlpk::Value LpGlpk::_getPrimal(int i)
   283   {
   284     return lpx_get_col_prim(lp,i);
   285   }
   286   
   287   LpGlpk::Value LpGlpk::_getPrimalValue()
   288   {
   289     return lpx_get_obj_val(lp);
   290   }
   291   
   292  
   293   LpGlpk::SolutionStatus LpGlpk::_getPrimalStatus()
   294   {
   295     int stat=  lpx_get_status(lp);
   296     switch (stat) {
   297     case LPX_UNDEF://Undefined (no solve has been run yet)
   298       return UNDEFINED;
   299       break;
   300     case LPX_NOFEAS://There is no feasible solution (primal, I guess)
   301     case LPX_INFEAS://Infeasible 
   302       return INFEASIBLE;
   303       break;
   304     case LPX_UNBND://Unbounded
   305       return INFINITE;
   306       break;
   307     case LPX_FEAS://Feasible
   308       return FEASIBLE;
   309       break;
   310     case LPX_OPT://Feasible
   311       return OPTIMAL;
   312       break;
   313     default:
   314       return UNDEFINED; //to avoid gcc warning
   315       //FIXME error
   316     }
   317   }
   318 
   319 
   320   void LpGlpk::_setMax()
   321   {
   322     lpx_set_obj_dir(lp, LPX_MAX);
   323   }
   324 
   325   void LpGlpk::_setMin()
   326   {
   327     lpx_set_obj_dir(lp, LPX_MIN);
   328   }
   329 
   330  
   331   void LpGlpk::messageLevel(int m)
   332   {
   333     lpx_set_int_parm(lp, LPX_K_MSGLEV, m);
   334   }
   335 
   336   void LpGlpk::presolver(bool b)
   337   {
   338     lpx_set_int_parm(lp, LPX_K_PRESOL, b);
   339   }
   340 
   341  
   342 } //END OF NAMESPACE LEMON
   343 
   344 #endif //LEMON_LP_GLPK_CC