lemon/lp_glpk.cc
changeset 2542 faaa54ec4520
parent 2391 14a343be7a5a
child 2553 bfced05fa852
equal deleted inserted replaced
27:db9d5718fa07 28:4aef8402810d
    19 ///\file
    19 ///\file
    20 ///\brief Implementation of the LEMON-GLPK lp solver interface.
    20 ///\brief Implementation of the LEMON-GLPK lp solver interface.
    21 
    21 
    22 #include <lemon/lp_glpk.h>
    22 #include <lemon/lp_glpk.h>
    23 //#include <iostream>
    23 //#include <iostream>
       
    24 
       
    25 #if GLP_MAJOR_VERSION > 4 || (GLP_MAJOR_VERSION == 4 && GLP_MINOR_VERSION > 15)
       
    26 #define LEMON_glp(func) (glp_##func)
       
    27 #define LEMON_lpx(func) (lpx_##func)
       
    28 
       
    29 #define LEMON_GLP(def) (GLP_##def)
       
    30 #define LEMON_LPX(def) (LPX_##def)
       
    31 
       
    32 #else
       
    33 
       
    34 #define LEMON_glp(func) (lpx_##func)
       
    35 #define LEMON_lpx(func) (lpx_##func)
       
    36 
       
    37 #define LEMON_GLP(def) (LPX_##def)
       
    38 #define LEMON_LPX(def) (LPX_##def)
       
    39 
       
    40 #endif
       
    41 
    24 namespace lemon {
    42 namespace lemon {
    25 
    43 
    26 
       
    27   LpGlpk::LpGlpk() : Parent() {
    44   LpGlpk::LpGlpk() : Parent() {
       
    45     solved = false;
    28     rows = _lp_bits::LpId(1);
    46     rows = _lp_bits::LpId(1);
    29     cols = _lp_bits::LpId(1);
    47     cols = _lp_bits::LpId(1);
    30     lp = lpx_create_prob();
    48     lp = LEMON_glp(create_prob)();
    31     lpx_create_index(lp);
    49     LEMON_glp(create_index)(lp);
    32     ///\todo control function for this:
    50     LEMON_lpx(set_int_parm)(lp, LEMON_LPX(K_DUAL), 1);
    33     lpx_set_int_parm(lp, LPX_K_DUAL, 1);
       
    34     messageLevel(0);
    51     messageLevel(0);
    35   }
    52   }
    36   
    53   
    37   LpGlpk::LpGlpk(const LpGlpk &glp) : Parent() {
    54   LpGlpk::LpGlpk(const LpGlpk &glp) : Parent() {
       
    55     solved = false;
    38     rows = _lp_bits::LpId(1);
    56     rows = _lp_bits::LpId(1);
    39     cols = _lp_bits::LpId(1);
    57     cols = _lp_bits::LpId(1);
    40     lp = lpx_create_prob();
    58     lp = LEMON_glp(create_prob)();
    41     lpx_create_index(lp);
    59     LEMON_glp(create_index)(lp);
    42     ///\todo control function for this:
    60     ///\todo control function for this:
    43     lpx_set_int_parm(lp, LPX_K_DUAL, 1);
    61     LEMON_lpx(set_int_parm)(lp, LEMON_LPX(K_DUAL), 1);
    44     messageLevel(0);
    62     messageLevel(0);
    45     //Coefficient matrix, row bounds
    63     //Coefficient matrix, row bounds
    46     lpx_add_rows(lp, lpx_get_num_rows(glp.lp));
    64     LEMON_glp(add_rows)(lp, LEMON_glp(get_num_rows)(glp.lp));
    47     lpx_add_cols(lp, lpx_get_num_cols(glp.lp));
    65     LEMON_glp(add_cols)(lp, LEMON_glp(get_num_cols)(glp.lp));
    48     int len;
    66     int len;
    49     int ind[1+lpx_get_num_cols(glp.lp)];
    67     int ind[1+LEMON_glp(get_num_cols)(glp.lp)];
    50     Value val[1+lpx_get_num_cols(glp.lp)];
    68     Value val[1+LEMON_glp(get_num_cols)(glp.lp)];
    51     for (int i=1;i<=lpx_get_num_rows(glp.lp);++i)
    69     for (int i=1;i<=LEMON_glp(get_num_rows)(glp.lp);++i)
    52       {
    70       {
    53 	len=lpx_get_mat_row(glp.lp,i,ind,val);
    71 	len=LEMON_glp(get_mat_row)(glp.lp,i,ind,val);
    54 	lpx_set_mat_row(lp, i,len,ind,val);
    72 	LEMON_glp(set_mat_row)(lp, i,len,ind,val);
    55 	lpx_set_row_bnds(lp,i,lpx_get_row_type(glp.lp,i),
    73 	LEMON_glp(set_row_bnds)(lp,i,
    56 			 lpx_get_row_lb(glp.lp,i),lpx_get_row_ub(glp.lp,i));
    74 				LEMON_glp(get_row_type)(glp.lp,i),
       
    75 				LEMON_glp(get_row_lb)(glp.lp,i),
       
    76 				LEMON_glp(get_row_ub)(glp.lp,i));
    57       }
    77       }
    58 
    78 
    59     //Objective function, coloumn bounds
    79     //Objective function, coloumn bounds
    60     lpx_set_obj_dir(lp, lpx_get_obj_dir(glp.lp));
    80     LEMON_glp(set_obj_dir)(lp, LEMON_glp(get_obj_dir)(glp.lp));
    61     //Objectif function's constant term treated separately
    81     //Objectif function's constant term treated separately
    62     lpx_set_obj_coef(lp,0,lpx_get_obj_coef(glp.lp,0));
    82     LEMON_glp(set_obj_coef)(lp,0,LEMON_glp(get_obj_coef)(glp.lp,0));
    63     for (int i=1;i<=lpx_get_num_cols(glp.lp);++i)
    83     for (int i=1;i<=LEMON_glp(get_num_cols)(glp.lp);++i)
    64       {
    84       {
    65 	lpx_set_obj_coef(lp,i,lpx_get_obj_coef(glp.lp,i));
    85 	LEMON_glp(set_obj_coef)(lp,i,
    66 	lpx_set_col_bnds(lp,i,lpx_get_col_type(glp.lp,i),
    86 				LEMON_glp(get_obj_coef)(glp.lp,i));
    67 			 lpx_get_col_lb(glp.lp,i),lpx_get_col_ub(glp.lp,i));
    87 	LEMON_glp(set_col_bnds)(lp,i,
       
    88 				LEMON_glp(get_col_type)(glp.lp,i),
       
    89 				LEMON_glp(get_col_lb)(glp.lp,i),
       
    90 				LEMON_glp(get_col_ub)(glp.lp,i));
    68       }
    91       }
    69   }
    92   }
    70   
    93   
    71   LpGlpk::~LpGlpk() {
    94   LpGlpk::~LpGlpk() {
    72     lpx_delete_prob(lp);
    95     LEMON_glp(delete_prob)(lp);
    73   }
    96   }
    74   
    97   
    75   int LpGlpk::_addCol() { 
    98   int LpGlpk::_addCol() { 
    76     int i=lpx_add_cols(lp, 1);
    99     int i=LEMON_glp(add_cols)(lp, 1);
    77     _setColLowerBound(i, -INF);
   100     LEMON_glp(set_col_bnds)(lp, i, LEMON_GLP(FR), 0.0, 0.0);
    78     _setColUpperBound(i, INF);
   101     solved = false;
    79     return i;
   102     return i;
    80   }
   103   }
    81 
   104 
    82   ///\e
   105   ///\e
    83 
   106 
    95     LpGlpk* newlp=new LpGlpk(*this);
   118     LpGlpk* newlp=new LpGlpk(*this);
    96     return *newlp;
   119     return *newlp;
    97   }
   120   }
    98 
   121 
    99   int LpGlpk::_addRow() { 
   122   int LpGlpk::_addRow() { 
   100     int i=lpx_add_rows(lp, 1);
   123     int i=LEMON_glp(add_rows)(lp, 1);
       
   124     solved = false;
   101     return i;
   125     return i;
   102   }
   126   }
   103 
   127 
   104   
   128   
   105   void LpGlpk::_eraseCol(int i) {
   129   void LpGlpk::_eraseCol(int i) {
   106     int ca[2];
   130     int ca[2];
   107     ca[1]=i;
   131     ca[1]=i;
   108     lpx_del_cols(lp, 1, ca);
   132     LEMON_glp(del_cols)(lp, 1, ca);
       
   133     solved = false;
   109   }
   134   }
   110   
   135   
   111   void LpGlpk::_eraseRow(int i) {
   136   void LpGlpk::_eraseRow(int i) {
   112     int ra[2];
   137     int ra[2];
   113     ra[1]=i;
   138     ra[1]=i;
   114     lpx_del_rows(lp, 1, ra);
   139     LEMON_glp(del_rows)(lp, 1, ra);
       
   140     solved = false;
   115   }
   141   }
   116 
   142 
   117   void LpGlpk::_getColName(int c, std::string & name) const
   143   void LpGlpk::_getColName(int c, std::string & name) const
   118   {
   144   {
   119     
   145     
   120     char *n = lpx_get_col_name(lp,c);
   146     const char *n = LEMON_glp(get_col_name)(lp,c);
   121     name = n?n:"";
   147     name = n?n:"";
   122   }
   148   }
   123   
   149   
   124   
   150   
   125   void LpGlpk::_setColName(int c, const std::string & name)
   151   void LpGlpk::_setColName(int c, const std::string & name)
   126   {
   152   {
   127     lpx_set_col_name(lp,c,const_cast<char*>(name.c_str()));
   153     LEMON_glp(set_col_name)(lp,c,const_cast<char*>(name.c_str()));
   128 
   154 
   129   }
   155   }
   130 
   156 
   131   int LpGlpk::_colByName(const std::string& name) const
   157   int LpGlpk::_colByName(const std::string& name) const
   132   {
   158   {
   133     int k = lpx_find_col(lp, const_cast<char*>(name.c_str()));
   159     int k = LEMON_glp(find_col)(lp, const_cast<char*>(name.c_str()));
   134     return k > 0 ? k : -1; 
   160     return k > 0 ? k : -1; 
   135   }
   161   }
   136 
   162 
   137   
   163   
   138   void LpGlpk::_setRowCoeffs(int i, ConstRowIterator b, ConstRowIterator e) 
   164   void LpGlpk::_setRowCoeffs(int i, ConstRowIterator b, ConstRowIterator e) 
   146     for(ConstRowIterator it=b; it!=e; ++it) {
   172     for(ConstRowIterator it=b; it!=e; ++it) {
   147       indices.push_back(it->first);
   173       indices.push_back(it->first);
   148       values.push_back(it->second);
   174       values.push_back(it->second);
   149     }
   175     }
   150 
   176 
   151     lpx_set_mat_row(lp, i, values.size() - 1, &indices[0], &values[0]);
   177     LEMON_glp(set_mat_row)(lp, i, values.size() - 1, 
       
   178 				&indices[0], &values[0]);
       
   179 
       
   180     solved = false;
   152   }
   181   }
   153 
   182 
   154   void LpGlpk::_getRowCoeffs(int ix, RowIterator b) const
   183   void LpGlpk::_getRowCoeffs(int ix, RowIterator b) const
   155   {
   184   {
   156     int length = lpx_get_mat_row(lp, ix, 0, 0);
   185     int length = LEMON_glp(get_mat_row)(lp, ix, 0, 0);
   157     
   186     
   158     std::vector<int> indices(length + 1);
   187     std::vector<int> indices(length + 1);
   159     std::vector<Value> values(length + 1);
   188     std::vector<Value> values(length + 1);
   160     
   189     
   161     lpx_get_mat_row(lp, ix, &indices[0], &values[0]);
   190     LEMON_glp(get_mat_row)(lp, ix, &indices[0], &values[0]);
   162     
   191     
   163     for (int i = 1; i <= length; ++i) {
   192     for (int i = 1; i <= length; ++i) {
   164       *b = std::make_pair(indices[i], values[i]);
   193       *b = std::make_pair(indices[i], values[i]);
   165       ++b;
   194       ++b;
   166     }
   195     }
   177     for(ConstColIterator it=b; it!=e; ++it) {
   206     for(ConstColIterator it=b; it!=e; ++it) {
   178       indices.push_back(it->first);
   207       indices.push_back(it->first);
   179       values.push_back(it->second);
   208       values.push_back(it->second);
   180     }
   209     }
   181     
   210     
   182     lpx_set_mat_col(lp, ix, values.size() - 1, &indices[0], &values[0]);
   211     LEMON_glp(set_mat_col)(lp, ix, values.size() - 1, 
       
   212 				&indices[0], &values[0]);
       
   213 
       
   214     solved = false;
   183   }
   215   }
   184 
   216 
   185   void LpGlpk::_getColCoeffs(int ix, ColIterator b) const
   217   void LpGlpk::_getColCoeffs(int ix, ColIterator b) const
   186   {
   218   {
   187     int length = lpx_get_mat_col(lp, ix, 0, 0);
   219     int length = LEMON_glp(get_mat_col)(lp, ix, 0, 0);
   188     
   220     
   189     std::vector<int> indices(length + 1);
   221     std::vector<int> indices(length + 1);
   190     std::vector<Value> values(length + 1);
   222     std::vector<Value> values(length + 1);
   191     
   223     
   192     lpx_get_mat_col(lp, ix, &indices[0], &values[0]);
   224     LEMON_glp(get_mat_col)(lp, ix, &indices[0], &values[0]);
   193     
   225     
   194     for (int i = 1; i <= length; ++i) {
   226     for (int i = 1; i <= length; ++i) {
   195       *b = std::make_pair(indices[i], values[i]);
   227       *b = std::make_pair(indices[i], values[i]);
   196       ++b;
   228       ++b;
   197     }
   229     }
   198   }
   230   }
   199 
   231 
   200   void LpGlpk::_setCoeff(int ix, int jx, Value value) 
   232   void LpGlpk::_setCoeff(int ix, int jx, Value value) 
   201   {
   233   {
   202 
   234 
   203     if (lpx_get_num_cols(lp) < lpx_get_num_rows(lp)) {
   235     if (LEMON_glp(get_num_cols)(lp) < LEMON_glp(get_num_rows)(lp)) {
   204 
   236 
   205       int length=lpx_get_mat_row(lp, ix, 0, 0);
   237       int length=LEMON_glp(get_mat_row)(lp, ix, 0, 0);
   206       
   238       
   207       std::vector<int> indices(length + 2);
   239       std::vector<int> indices(length + 2);
   208       std::vector<Value> values(length + 2);
   240       std::vector<Value> values(length + 2);
   209       
   241       
   210       lpx_get_mat_row(lp, ix, &indices[0], &values[0]);
   242       LEMON_glp(get_mat_row)(lp, ix, &indices[0], &values[0]);
   211       
   243       
   212       //The following code does not suppose that the elements of the
   244       //The following code does not suppose that the elements of the
   213       //array indices are sorted
   245       //array indices are sorted
   214       bool found=false;
   246       bool found=false;
   215       for (int i = 1; i <= length; ++i) {
   247       for (int i = 1; i <= length; ++i) {
   223         ++length;
   255         ++length;
   224         indices[length]=jx;
   256         indices[length]=jx;
   225         values[length]=value;
   257         values[length]=value;
   226       }
   258       }
   227     
   259     
   228       lpx_set_mat_row(lp, ix, length, &indices[0], &values[0]);
   260       LEMON_glp(set_mat_row)(lp, ix, length, &indices[0], &values[0]);
   229 
   261 
   230     } else {
   262     } else {
   231 
   263 
   232       int length=lpx_get_mat_col(lp, jx, 0, 0);
   264       int length=LEMON_glp(get_mat_col)(lp, jx, 0, 0);
   233       
   265       
   234       std::vector<int> indices(length + 2);
   266       std::vector<int> indices(length + 2);
   235       std::vector<Value> values(length + 2);
   267       std::vector<Value> values(length + 2);
   236       
   268       
   237       lpx_get_mat_col(lp, jx, &indices[0], &values[0]);
   269       LEMON_glp(get_mat_col)(lp, jx, &indices[0], &values[0]);
   238       
   270       
   239       //The following code does not suppose that the elements of the
   271       //The following code does not suppose that the elements of the
   240       //array indices are sorted
   272       //array indices are sorted
   241       bool found=false;
   273       bool found=false;
   242       for (int i = 1; i <= length; ++i) {
   274       for (int i = 1; i <= length; ++i) {
   250         ++length;
   282         ++length;
   251         indices[length]=ix;
   283         indices[length]=ix;
   252         values[length]=value;
   284         values[length]=value;
   253       }
   285       }
   254     
   286     
   255       lpx_set_mat_col(lp, jx, length, &indices[0], &values[0]);
   287       LEMON_glp(set_mat_col)(lp, jx, length, &indices[0], &values[0]);
   256     }
   288     }
       
   289 
       
   290     solved = false;
   257   }
   291   }
   258 
   292 
   259   LpGlpk::Value LpGlpk::_getCoeff(int ix, int jx) const
   293   LpGlpk::Value LpGlpk::_getCoeff(int ix, int jx) const
   260   {
   294   {
   261 
   295 
   262     int length=lpx_get_mat_row(lp, ix, 0, 0);
   296     int length=LEMON_glp(get_mat_row)(lp, ix, 0, 0);
   263     
   297     
   264     std::vector<int> indices(length + 1);
   298     std::vector<int> indices(length + 1);
   265     std::vector<Value> values(length + 1);
   299     std::vector<Value> values(length + 1);
   266     
   300     
   267     lpx_get_mat_row(lp, ix, &indices[0], &values[0]);
   301     LEMON_glp(get_mat_row)(lp, ix, &indices[0], &values[0]);
   268     
   302     
   269     //The following code does not suppose that the elements of the
   303     //The following code does not suppose that the elements of the
   270     //array indices are sorted
   304     //array indices are sorted
   271     for (int i = 1; i <= length; ++i) {
   305     for (int i = 1; i <= length; ++i) {
   272       if (indices[i]==jx){
   306       if (indices[i]==jx){
   281   void LpGlpk::_setColLowerBound(int i, Value lo)
   315   void LpGlpk::_setColLowerBound(int i, Value lo)
   282   {
   316   {
   283     if (lo==INF) {
   317     if (lo==INF) {
   284       //FIXME error
   318       //FIXME error
   285     }
   319     }
   286     int b=lpx_get_col_type(lp, i);
   320     int b=LEMON_glp(get_col_type)(lp, i);
   287     double up=lpx_get_col_ub(lp, i);	
   321     double up=LEMON_glp(get_col_ub)(lp, i);	
   288     if (lo==-INF) {
   322     if (lo==-INF) {
   289       switch (b) {
   323       switch (b) {
   290       case LPX_FR:
   324       case LEMON_GLP(FR):
   291       case LPX_LO:
   325       case LEMON_GLP(LO):
   292 	lpx_set_col_bnds(lp, i, LPX_FR, lo, up);
   326 	LEMON_glp(set_col_bnds)(lp, i, LEMON_GLP(FR), lo, up);
   293 	break;
   327 	break;
   294       case LPX_UP:
   328       case LEMON_GLP(UP):
   295 	break;
   329 	break;
   296       case LPX_DB:
   330       case LEMON_GLP(DB):
   297       case LPX_FX:
   331       case LEMON_GLP(FX):
   298 	lpx_set_col_bnds(lp, i, LPX_UP, lo, up);
   332 	LEMON_glp(set_col_bnds)(lp, i, LEMON_GLP(UP), lo, up);
   299 	break;
   333 	break;
   300       default: ;
   334       default: ;
   301 	//FIXME error
   335 	//FIXME error
   302       }
   336       }
   303     } else {
   337     } else {
   304       switch (b) {
   338       switch (b) {
   305       case LPX_FR:
   339       case LEMON_GLP(FR):
   306       case LPX_LO:
   340       case LEMON_GLP(LO):
   307 	lpx_set_col_bnds(lp, i, LPX_LO, lo, up);
   341 	LEMON_glp(set_col_bnds)(lp, i, LEMON_GLP(LO), lo, up);
   308 	break;
   342 	break;
   309       case LPX_UP:	  
   343       case LEMON_GLP(UP):	  
   310       case LPX_DB:
   344       case LEMON_GLP(DB):
   311       case LPX_FX:
   345       case LEMON_GLP(FX):
   312 	if (lo==up) 
   346 	if (lo==up) 
   313 	  lpx_set_col_bnds(lp, i, LPX_FX, lo, up);
   347 	  LEMON_glp(set_col_bnds)(lp, i, LEMON_GLP(FX), lo, up);
   314 	else 
   348 	else 
   315 	  lpx_set_col_bnds(lp, i, LPX_DB, lo, up);
   349 	  LEMON_glp(set_col_bnds)(lp, i, LEMON_GLP(DB), lo, up);
   316 	break;
   350 	break;
   317       default: ;
   351       default: ;
   318 	//FIXME error
   352 	//FIXME error
   319       }
   353       }
   320     }
   354     }
   321 
   355 
       
   356     solved = false;
   322   }
   357   }
   323 
   358 
   324   LpGlpk::Value LpGlpk::_getColLowerBound(int i) const
   359   LpGlpk::Value LpGlpk::_getColLowerBound(int i) const
   325   {
   360   {
   326     int b=lpx_get_col_type(lp, i);
   361     int b=LEMON_glp(get_col_type)(lp, i);
   327       switch (b) {
   362       switch (b) {
   328       case LPX_LO:
   363       case LEMON_GLP(LO):
   329       case LPX_DB:
   364       case LEMON_GLP(DB):
   330       case LPX_FX:
   365       case LEMON_GLP(FX):
   331 	return lpx_get_col_lb(lp, i);	
   366 	return LEMON_glp(get_col_lb)(lp, i);	
   332       default: ;
   367       default: ;
   333 	return -INF;
   368 	return -INF;
   334       }
   369       }
   335   }
   370   }
   336   
   371   
   337   void LpGlpk::_setColUpperBound(int i, Value up)
   372   void LpGlpk::_setColUpperBound(int i, Value up)
   338   {
   373   {
   339     if (up==-INF) {
   374     if (up==-INF) {
   340       //FIXME error
   375       //FIXME error
   341     }
   376     }
   342     int b=lpx_get_col_type(lp, i);
   377     int b=LEMON_glp(get_col_type)(lp, i);
   343     double lo=lpx_get_col_lb(lp, i);
   378     double lo=LEMON_glp(get_col_lb)(lp, i);
   344     if (up==INF) {
   379     if (up==INF) {
   345       switch (b) {
   380       switch (b) {
   346       case LPX_FR:
   381       case LEMON_GLP(FR):
   347       case LPX_LO:
   382       case LEMON_GLP(LO):
   348 	break;
   383 	break;
   349       case LPX_UP:
   384       case LEMON_GLP(UP):
   350 	lpx_set_col_bnds(lp, i, LPX_FR, lo, up);
   385 	LEMON_glp(set_col_bnds)(lp, i, LEMON_GLP(FR), lo, up);
   351 	break;
   386 	break;
   352       case LPX_DB:
   387       case LEMON_GLP(DB):
   353       case LPX_FX:
   388       case LEMON_GLP(FX):
   354 	lpx_set_col_bnds(lp, i, LPX_LO, lo, up);
   389 	LEMON_glp(set_col_bnds)(lp, i, LEMON_GLP(LO), lo, up);
   355 	break;
   390 	break;
   356       default: ;
   391       default: ;
   357 	//FIXME error
   392 	//FIXME error
   358       }
   393       }
   359     } else {
   394     } else {
   360       switch (b) {
   395       switch (b) {
   361       case LPX_FR:
   396       case LEMON_GLP(FR):
   362 	lpx_set_col_bnds(lp, i, LPX_UP, lo, up);
   397 	LEMON_glp(set_col_bnds)(lp, i, LEMON_GLP(UP), lo, up);
   363 	break;
   398 	break;
   364       case LPX_UP:
   399       case LEMON_GLP(UP):
   365 	lpx_set_col_bnds(lp, i, LPX_UP, lo, up);
   400 	LEMON_glp(set_col_bnds)(lp, i, LEMON_GLP(UP), lo, up);
   366 	break;
   401 	break;
   367       case LPX_LO:
   402       case LEMON_GLP(LO):
   368       case LPX_DB:
   403       case LEMON_GLP(DB):
   369       case LPX_FX:
   404       case LEMON_GLP(FX):
   370 	if (lo==up) 
   405 	if (lo==up) 
   371 	  lpx_set_col_bnds(lp, i, LPX_FX, lo, up);
   406 	  LEMON_glp(set_col_bnds)(lp, i, LEMON_GLP(FX), lo, up);
   372 	else 
   407 	else 
   373 	  lpx_set_col_bnds(lp, i, LPX_DB, lo, up);
   408 	  LEMON_glp(set_col_bnds)(lp, i, LEMON_GLP(DB), lo, up);
   374 	break;
   409 	break;
   375       default: ;
   410       default: ;
   376 	//FIXME error
   411 	//FIXME error
   377       }
   412       }
   378     }
   413     }
       
   414 
       
   415     solved = false;
   379   }
   416   }
   380 
   417 
   381   LpGlpk::Value LpGlpk::_getColUpperBound(int i) const
   418   LpGlpk::Value LpGlpk::_getColUpperBound(int i) const
   382   {
   419   {
   383     int b=lpx_get_col_type(lp, i);
   420     int b=LEMON_glp(get_col_type)(lp, i);
   384       switch (b) {
   421       switch (b) {
   385       case LPX_UP:
   422       case LEMON_GLP(UP):
   386       case LPX_DB:
   423       case LEMON_GLP(DB):
   387       case LPX_FX:
   424       case LEMON_GLP(FX):
   388 	return lpx_get_col_ub(lp, i);	
   425 	return LEMON_glp(get_col_ub)(lp, i);	
   389       default: ;
   426       default: ;
   390 	return INF;
   427 	return INF;
   391       }
   428       }
   392   }
   429   }
   393   
   430   
   398       //FIXME error
   435       //FIXME error
   399     }
   436     }
   400 
   437 
   401     if (lb == -INF){
   438     if (lb == -INF){
   402       if (ub == INF){
   439       if (ub == INF){
   403 	lpx_set_row_bnds(lp, i, LPX_FR, lb, ub);
   440 	LEMON_glp(set_row_bnds)(lp, i, LEMON_GLP(FR), lb, ub);
   404       }
   441       }
   405       else{
   442       else{
   406 	lpx_set_row_bnds(lp, i, LPX_UP, lb, ub);
   443 	LEMON_glp(set_row_bnds)(lp, i, LEMON_GLP(UP), lb, ub);
   407       }
   444       }
   408     }
   445     }
   409     else{
   446     else{
   410       if (ub==INF){
   447       if (ub==INF){
   411 	lpx_set_row_bnds(lp, i, LPX_LO, lb, ub);
   448 	LEMON_glp(set_row_bnds)(lp, i, LEMON_GLP(LO), lb, ub);
   412 
   449 
   413       }
   450       }
   414       else{
   451       else{
   415 	if (lb == ub){
   452 	if (lb == ub){
   416 	  lpx_set_row_bnds(lp, i, LPX_FX, lb, ub);
   453 	  LEMON_glp(set_row_bnds)(lp, i, LEMON_GLP(FX), lb, ub);
   417 	}
   454 	}
   418 	else{
   455 	else{
   419 	  lpx_set_row_bnds(lp, i, LPX_DB, lb, ub);
   456 	  LEMON_glp(set_row_bnds)(lp, i, LEMON_GLP(DB), lb, ub);
   420 	}
   457 	}
   421       }
   458       }
   422     }
   459     }
   423 
   460 
       
   461     solved = false;
   424   }
   462   }
   425 
   463 
   426   void LpGlpk::_getRowBounds(int i, Value &lb, Value &ub) const
   464   void LpGlpk::_getRowBounds(int i, Value &lb, Value &ub) const
   427   {
   465   {
   428 
   466 
   429     int b=lpx_get_row_type(lp, i);
   467     int b=LEMON_glp(get_row_type)(lp, i);
   430     switch (b) {
   468     switch (b) {
   431     case LPX_FR:
   469     case LEMON_GLP(FR):
   432     case LPX_UP:
   470     case LEMON_GLP(UP):
   433       lb = -INF;
   471       lb = -INF;
   434 	break;
   472 	break;
   435     default: 
   473     default: 
   436       lb=lpx_get_row_lb(lp, i);
   474       lb=LEMON_glp(get_row_lb)(lp, i);
   437     }
   475     }
   438 
   476 
   439     switch (b) {
   477     switch (b) {
   440     case LPX_FR:
   478     case LEMON_GLP(FR):
   441     case LPX_LO:
   479     case LEMON_GLP(LO):
   442       ub = INF;
   480       ub = INF;
   443 	break;
   481 	break;
   444     default: 
   482     default: 
   445       ub=lpx_get_row_ub(lp, i);
   483       ub=LEMON_glp(get_row_ub)(lp, i);
   446     }
   484     }
   447     
   485     
   448   }
   486   }
   449   
   487   
   450   void LpGlpk::_setObjCoeff(int i, Value obj_coef)
   488   void LpGlpk::_setObjCoeff(int i, Value obj_coef)
   451   {
   489   {
   452     //i=0 means the constant term (shift)
   490     //i=0 means the constant term (shift)
   453     lpx_set_obj_coef(lp, i, obj_coef);
   491     LEMON_glp(set_obj_coef)(lp, i, obj_coef);
       
   492 
       
   493     solved = false;
   454   }
   494   }
   455 
   495 
   456   LpGlpk::Value LpGlpk::_getObjCoeff(int i) const {
   496   LpGlpk::Value LpGlpk::_getObjCoeff(int i) const {
   457     //i=0 means the constant term (shift)
   497     //i=0 means the constant term (shift)
   458     return lpx_get_obj_coef(lp, i);
   498     return LEMON_glp(get_obj_coef)(lp, i);
   459   }
   499   }
   460 
   500 
   461   void LpGlpk::_clearObj()
   501   void LpGlpk::_clearObj()
   462   {
   502   {
   463     for (int i=0;i<=lpx_get_num_cols(lp);++i){
   503     for (int i=0;i<=LEMON_glp(get_num_cols)(lp);++i){
   464       lpx_set_obj_coef(lp, i, 0);
   504       LEMON_glp(set_obj_coef)(lp, i, 0);
   465     }
   505     }
       
   506 
       
   507     solved = false;
   466   }
   508   }
   467 
   509 
   468   LpGlpk::SolveExitStatus LpGlpk::_solve()
   510   LpGlpk::SolveExitStatus LpGlpk::_solve()
   469   {
   511   {
   470     // A way to check the problem to be solved
   512     // A way to check the problem to be solved
   471     //lpx_write_cpxlp(lp,"naittvan.cpx");    
   513     //LEMON_glp(write_cpxlp(lp,"naittvan.cpx");    
   472 
   514 
   473     lpx_std_basis(lp);
   515     LEMON_lpx(std_basis)(lp);
   474     int i =  lpx_simplex(lp);
   516     int i =  LEMON_lpx(simplex)(lp);
   475     
   517     
   476     switch (i) {
   518     switch (i) {
   477     case LPX_E_OK: 
   519     case LEMON_LPX(E_OK): 
       
   520       solved = true;
   478       return SOLVED;
   521       return SOLVED;
   479     default:
   522     default:
   480       return UNSOLVED;
   523       return UNSOLVED;
   481     }
   524     }
   482   }
   525   }
   483 
   526 
   484   LpGlpk::Value LpGlpk::_getPrimal(int i) const
   527   LpGlpk::Value LpGlpk::_getPrimal(int i) const
   485   {
   528   {
   486     return lpx_get_col_prim(lp,i);
   529     return LEMON_glp(get_col_prim)(lp,i);
   487   }
   530   }
   488 
   531 
   489   LpGlpk::Value LpGlpk::_getDual(int i) const
   532   LpGlpk::Value LpGlpk::_getDual(int i) const
   490   {
   533   {
   491     return lpx_get_row_dual(lp,i);
   534     return LEMON_glp(get_row_dual)(lp,i);
   492   }
   535   }
   493   
   536   
   494   LpGlpk::Value LpGlpk::_getPrimalValue() const
   537   LpGlpk::Value LpGlpk::_getPrimalValue() const
   495   {
   538   {
   496     return lpx_get_obj_val(lp);
   539     return LEMON_glp(get_obj_val)(lp);
   497   }
   540   }
   498   bool LpGlpk::_isBasicCol(int i) const
   541   bool LpGlpk::_isBasicCol(int i) const
   499   {
   542   {
   500     return (lpx_get_col_stat(lp, i)==LPX_BS);
   543     return (LEMON_glp(get_col_stat)(lp, i)==LEMON_GLP(BS));
   501   }
   544   }
   502   
   545   
   503  
   546  
   504   LpGlpk::SolutionStatus LpGlpk::_getPrimalStatus() const
   547   LpGlpk::SolutionStatus LpGlpk::_getPrimalStatus() const
   505   {
   548   {
   506     int stat=  lpx_get_status(lp);
   549     if (!solved) return UNDEFINED;
       
   550     int stat=  LEMON_lpx(get_status)(lp);
   507     switch (stat) {
   551     switch (stat) {
   508     case LPX_UNDEF://Undefined (no solve has been run yet)
   552     case LEMON_LPX(UNDEF)://Undefined (no solve has been run yet)
   509       return UNDEFINED;
   553       return UNDEFINED;
   510     case LPX_NOFEAS://There is no feasible solution (primal, I guess)
   554     case LEMON_LPX(NOFEAS)://There is no feasible solution (primal, I guess)
   511     case LPX_INFEAS://Infeasible 
   555     case LEMON_LPX(INFEAS)://Infeasible 
   512       return INFEASIBLE;
   556       return INFEASIBLE;
   513     case LPX_UNBND://Unbounded
   557     case LEMON_LPX(UNBND)://Unbounded
   514       return INFINITE;
   558       return INFINITE;
   515     case LPX_FEAS://Feasible
   559     case LEMON_LPX(FEAS)://Feasible
   516       return FEASIBLE;
   560       return FEASIBLE;
   517     case LPX_OPT://Feasible
   561     case LEMON_LPX(OPT)://Feasible
   518       return OPTIMAL;
   562       return OPTIMAL;
   519     default:
   563     default:
   520       return UNDEFINED; //to avoid gcc warning
   564       return UNDEFINED; //to avoid gcc warning
   521       //FIXME error
   565       //FIXME error
   522     }
   566     }
   523   }
   567   }
   524 
   568 
   525   LpGlpk::SolutionStatus LpGlpk::_getDualStatus() const
   569   LpGlpk::SolutionStatus LpGlpk::_getDualStatus() const
   526   {
   570   {
   527     switch (lpx_get_dual_stat(lp)) {
   571     if (!solved) return UNDEFINED;
   528     case LPX_D_UNDEF://Undefined (no solve has been run yet)
   572     switch (LEMON_lpx(get_dual_stat)(lp)) {
       
   573     case LEMON_LPX(D_UNDEF)://Undefined (no solve has been run yet)
   529       return UNDEFINED;
   574       return UNDEFINED;
   530     case LPX_D_NOFEAS://There is no dual feasible solution 
   575     case LEMON_LPX(D_NOFEAS)://There is no dual feasible solution 
   531 //    case LPX_D_INFEAS://Infeasible 
   576 //    case LEMON_LPX(D_INFEAS://Infeasible 
   532       return INFEASIBLE;
   577       return INFEASIBLE;
   533     case LPX_D_FEAS://Feasible    
   578     case LEMON_LPX(D_FEAS)://Feasible    
   534       switch (lpx_get_status(lp)) {
   579       switch (LEMON_lpx(get_status)(lp)) {
   535       case LPX_NOFEAS:
   580       case LEMON_LPX(NOFEAS):
   536 	return INFINITE;
   581 	return INFINITE;
   537       case LPX_OPT:
   582       case LEMON_LPX(OPT):
   538 	return OPTIMAL;
   583 	return OPTIMAL;
   539       default:
   584       default:
   540 	return FEASIBLE;
   585 	return FEASIBLE;
   541       }
   586       }
   542     default:
   587     default:
   545     }
   590     }
   546   }
   591   }
   547 
   592 
   548   LpGlpk::ProblemTypes LpGlpk::_getProblemType() const
   593   LpGlpk::ProblemTypes LpGlpk::_getProblemType() const
   549   {
   594   {
   550       //int stat=  lpx_get_status(lp);
   595     if (!solved) return UNKNOWN;
   551     int statp=  lpx_get_prim_stat(lp);
   596       //int stat=  LEMON_glp(get_status(lp);
   552     int statd=  lpx_get_dual_stat(lp);
   597     int statp=  LEMON_lpx(get_prim_stat)(lp);
   553     if (statp==LPX_P_FEAS && statd==LPX_D_FEAS)
   598     int statd=  LEMON_lpx(get_dual_stat)(lp);
       
   599     if (statp==LEMON_LPX(P_FEAS) && statd==LEMON_LPX(D_FEAS))
   554 	return PRIMAL_DUAL_FEASIBLE;
   600 	return PRIMAL_DUAL_FEASIBLE;
   555     if (statp==LPX_P_FEAS && statd==LPX_D_NOFEAS)
   601     if (statp==LEMON_LPX(P_FEAS) && statd==LEMON_LPX(D_NOFEAS))
   556 	return PRIMAL_FEASIBLE_DUAL_INFEASIBLE;
   602 	return PRIMAL_FEASIBLE_DUAL_INFEASIBLE;
   557     if (statp==LPX_P_NOFEAS && statd==LPX_D_FEAS)
   603     if (statp==LEMON_LPX(P_NOFEAS) && statd==LEMON_LPX(D_FEAS))
   558 	return PRIMAL_INFEASIBLE_DUAL_FEASIBLE;
   604 	return PRIMAL_INFEASIBLE_DUAL_FEASIBLE;
   559     if (statp==LPX_P_NOFEAS && statd==LPX_D_NOFEAS)
   605     if (statp==LEMON_LPX(P_NOFEAS) && statd==LEMON_LPX(D_NOFEAS))
   560 	return PRIMAL_DUAL_INFEASIBLE;
   606 	return PRIMAL_DUAL_INFEASIBLE;
   561     //In all other cases
   607     //In all other cases
   562     return UNKNOWN;
   608     return UNKNOWN;
   563   }
   609   }
   564 
   610 
   565   void LpGlpk::_setMax()
   611   void LpGlpk::_setMax()
   566   {
   612   {
   567     lpx_set_obj_dir(lp, LPX_MAX);
   613     solved = false;
       
   614     LEMON_glp(set_obj_dir)(lp, LEMON_GLP(MAX));
   568   }
   615   }
   569 
   616 
   570   void LpGlpk::_setMin()
   617   void LpGlpk::_setMin()
   571   {
   618   {
   572     lpx_set_obj_dir(lp, LPX_MIN);
   619     solved = false;
       
   620     LEMON_glp(set_obj_dir)(lp, LEMON_GLP(MIN));
   573   }
   621   }
   574 
   622 
   575   bool LpGlpk::_isMax() const
   623   bool LpGlpk::_isMax() const
   576   {
   624   {
   577     return (lpx_get_obj_dir(lp)==LPX_MAX);
   625     return (LEMON_glp(get_obj_dir)(lp)==LEMON_GLP(MAX));
   578   }
   626   }
   579 
   627 
   580  
   628  
   581 
   629 
   582   void LpGlpk::messageLevel(int m)
   630   void LpGlpk::messageLevel(int m)
   583   {
   631   {
   584     lpx_set_int_parm(lp, LPX_K_MSGLEV, m);
   632     LEMON_lpx(set_int_parm)(lp, LEMON_LPX(K_MSGLEV), m);
   585   }
   633   }
   586 
   634 
   587   void LpGlpk::presolver(bool b)
   635   void LpGlpk::presolver(bool b)
   588   {
   636   {
   589     lpx_set_int_parm(lp, LPX_K_PRESOL, b);
   637     LEMON_lpx(set_int_parm)(lp, LEMON_LPX(K_PRESOL), b);
   590   }
   638   }
   591 
   639 
   592  
   640  
   593 } //END OF NAMESPACE LEMON
   641 } //END OF NAMESPACE LEMON