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