Bug fix.
Default assign operator should be
overrided by that calls the template
assign operator.
     2  * lemon/lp_glpk.cc - Part of LEMON, a generic C++ optimization library
 
     4  * Copyright (C) 2005 Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
 
     5  * (Egervary Research Group on Combinatorial Optimization, EGRES).
 
     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.
 
    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
 
    17 #ifndef LEMON_LP_GLPK_CC
 
    18 #define LEMON_LP_GLPK_CC
 
    21 ///\brief Implementation of the LEMON-GLPK lp solver interface.
 
    23 #include <lemon/lp_glpk.h>
 
    28   LpGlpk::LpGlpk() : Parent(), 
 
    29 		     lp(lpx_create_prob()) {
 
    30     ///\todo constrol function for this:
 
    31     lpx_set_int_parm(lp, LPX_K_DUAL, 1);
 
    39   int LpGlpk::_addCol() { 
 
    40     int i=lpx_add_cols(lp, 1);
 
    41     _setColLowerBound(i, -INF);
 
    42     _setColUpperBound(i, INF);
 
    49   LpSolverBase &LpGlpk::_newLp()
 
    51     LpGlpk* newlp=new LpGlpk();
 
    57   LpSolverBase &LpGlpk::_copyLp()
 
    59     LpGlpk* newlp=new LpGlpk();
 
    61     //Coefficient matrix, row bounds
 
    62     lpx_add_rows(newlp->lp, lpx_get_num_rows(lp));
 
    63     lpx_add_cols(newlp->lp, lpx_get_num_cols(lp));
 
    65     int ind[1+lpx_get_num_cols(lp)];
 
    66     Value val[1+lpx_get_num_cols(lp)];
 
    67     for (int i=1;i<=lpx_get_num_rows(lp);++i){
 
    68       len=lpx_get_mat_row(lp,i,ind,val);
 
    69       lpx_set_mat_row(newlp->lp, i,len,ind,val);
 
    70       lpx_set_row_bnds(newlp->lp,i,lpx_get_row_type(lp,i),
 
    71 		       lpx_get_row_lb(lp,i),lpx_get_row_ub(lp,i));
 
    74     //Objective function, coloumn bounds
 
    75     lpx_set_obj_dir(newlp->lp, lpx_get_obj_dir(lp));
 
    76     //Objectif function's constant term treated separately
 
    77     lpx_set_obj_coef(newlp->lp,0,lpx_get_obj_coef(lp,0));
 
    78     for (int i=1;i<=lpx_get_num_cols(lp);++i){
 
    79       lpx_set_obj_coef(newlp->lp,i,lpx_get_obj_coef(lp,i));
 
    80       lpx_set_col_bnds(newlp->lp,i,lpx_get_col_type(lp,i),
 
    81 		       lpx_get_col_lb(lp,i),lpx_get_col_ub(lp,i));
 
    89   int LpGlpk::_addRow() { 
 
    90     int i=lpx_add_rows(lp, 1);
 
    95   void LpGlpk::_eraseCol(int i) {
 
    98     lpx_del_cols(lp, 1, cols);
 
   101   void LpGlpk::_eraseRow(int i) {
 
   104     lpx_del_rows(lp, 1, rows);
 
   107   void LpGlpk::_setRowCoeffs(int i, 
 
   110 			     const Value   * values )
 
   112     lpx_set_mat_row(lp, i, length,
 
   113 		    const_cast<int * >(indices) ,
 
   114 		    const_cast<Value * >(values));
 
   117   void LpGlpk::_setColCoeffs(int i, 
 
   120 			     const Value   * values)
 
   122     lpx_set_mat_col(lp, i, length,
 
   123 		    const_cast<int * >(indices),
 
   124 		    const_cast<Value * >(values));
 
   128   void LpGlpk::_setCoeff(int row, int col, Value value) 
 
   130     ///FIXME Of course this is not efficient at all, but GLPK knows not more.
 
   131     // First approach: get one row, apply changes and set it again
 
   132     //(one idea to improve this: maybe it is better to do this with 1 coloumn)
 
   134     int mem_length=2+lpx_get_num_cols(lp);
 
   135     int* indices = new int[mem_length];
 
   136     Value* values = new Value[mem_length];
 
   139     int length=lpx_get_mat_row(lp, row, indices, values);
 
   141     //The following code does not suppose that the elements of the array indices are sorted
 
   144     while (i <= length && !found){
 
   145       if (indices[i]==col){
 
   154       values[length]=value;
 
   157     lpx_set_mat_row(lp, row, length, indices, values);
 
   163   void LpGlpk::_setColLowerBound(int i, Value lo)
 
   168     int b=lpx_get_col_type(lp, i);
 
   169     double up=lpx_get_col_ub(lp, i);	
 
   174 	lpx_set_col_bnds(lp, i, LPX_FR, lo, up);
 
   180 	lpx_set_col_bnds(lp, i, LPX_UP, lo, up);
 
   189 	lpx_set_col_bnds(lp, i, LPX_LO, lo, up);
 
   195 	  lpx_set_col_bnds(lp, i, LPX_FX, lo, up);
 
   197 	  lpx_set_col_bnds(lp, i, LPX_DB, lo, up);
 
   206   void LpGlpk::_setColUpperBound(int i, Value up)
 
   211     int b=lpx_get_col_type(lp, i);
 
   212     double lo=lpx_get_col_lb(lp, i);
 
   219 	lpx_set_col_bnds(lp, i, LPX_FR, lo, up);
 
   223 	lpx_set_col_bnds(lp, i, LPX_LO, lo, up);
 
   231 	lpx_set_col_bnds(lp, i, LPX_UP, lo, up);
 
   234 	lpx_set_col_bnds(lp, i, LPX_UP, lo, up);
 
   240 	  lpx_set_col_bnds(lp, i, LPX_FX, lo, up);
 
   242 	  lpx_set_col_bnds(lp, i, LPX_DB, lo, up);
 
   250 //   void LpGlpk::_setRowLowerBound(int i, Value lo)
 
   255 //     int b=lpx_get_row_type(lp, i);
 
   256 //     double up=lpx_get_row_ub(lp, i);	
 
   261 // 	lpx_set_row_bnds(lp, i, LPX_FR, lo, up);
 
   267 // 	lpx_set_row_bnds(lp, i, LPX_UP, lo, up);
 
   276 // 	lpx_set_row_bnds(lp, i, LPX_LO, lo, up);
 
   282 // 	  lpx_set_row_bnds(lp, i, LPX_FX, lo, up);
 
   284 // 	  lpx_set_row_bnds(lp, i, LPX_DB, lo, up);
 
   292 //   void LpGlpk::_setRowUpperBound(int i, Value up)
 
   297 //     int b=lpx_get_row_type(lp, i);
 
   298 //     double lo=lpx_get_row_lb(lp, i);
 
   305 // 	lpx_set_row_bnds(lp, i, LPX_FR, lo, up);
 
   309 // 	lpx_set_row_bnds(lp, i, LPX_LO, lo, up);
 
   317 // 	lpx_set_row_bnds(lp, i, LPX_UP, lo, up);
 
   320 // 	lpx_set_row_bnds(lp, i, LPX_UP, lo, up);
 
   326 // 	  lpx_set_row_bnds(lp, i, LPX_FX, lo, up);
 
   328 // 	  lpx_set_row_bnds(lp, i, LPX_DB, lo, up);
 
   336   void LpGlpk::_setRowBounds(int i, Value lb, Value ub)
 
   339     if (lb==INF || ub==-INF) {
 
   345 	lpx_set_row_bnds(lp, i, LPX_FR, lb, ub);
 
   348 	lpx_set_row_bnds(lp, i, LPX_UP, lb, ub);
 
   353 	lpx_set_row_bnds(lp, i, LPX_LO, lb, ub);
 
   358 	  lpx_set_row_bnds(lp, i, LPX_FX, lb, ub);
 
   361 	  lpx_set_row_bnds(lp, i, LPX_DB, lb, ub);
 
   368   void LpGlpk::_setObjCoeff(int i, Value obj_coef)
 
   370     //i=0 means the constant term (shift)
 
   371     lpx_set_obj_coef(lp, i, obj_coef);
 
   374   void LpGlpk::_clearObj()
 
   376     for (int i=0;i<=lpx_get_num_cols(lp);++i){
 
   377       lpx_set_obj_coef(lp, i, 0);
 
   380 //   void LpGlpk::_setObj(int length,
 
   381 // 		       int  const * indices, 
 
   382 // 		       Value  const * values )
 
   384 //     Value new_values[1+lpx_num_cols()];
 
   385 //     for (i=0;i<=lpx_num_cols();++i){
 
   388 //     for (i=1;i<=length;++i){
 
   389 //       new_values[indices[i]]=values[i];
 
   392 //     for (i=0;i<=lpx_num_cols();++i){
 
   393 //       lpx_set_obj_coef(lp, i, new_values[i]);
 
   397   LpGlpk::SolveExitStatus LpGlpk::_solve()
 
   399     int i =  lpx_simplex(lp);
 
   408   LpGlpk::Value LpGlpk::_getPrimal(int i)
 
   410     return lpx_get_col_prim(lp,i);
 
   413   LpGlpk::Value LpGlpk::_getPrimalValue()
 
   415     return lpx_get_obj_val(lp);
 
   419   LpGlpk::SolutionStatus LpGlpk::_getPrimalStatus()
 
   421     int stat=  lpx_get_status(lp);
 
   423     case LPX_UNDEF://Undefined (no solve has been run yet)
 
   425     case LPX_NOFEAS://There is no feasible solution (primal, I guess)
 
   426     case LPX_INFEAS://Infeasible 
 
   428     case LPX_UNBND://Unbounded
 
   430     case LPX_FEAS://Feasible
 
   432     case LPX_OPT://Feasible
 
   435       return UNDEFINED; //to avoid gcc warning
 
   440   LpGlpk::SolutionStatus LpGlpk::_getDualStatus()
 
   442 //     std::cout<<"Itt megy: "<<lpx_get_dual_stat(lp)<<std::endl;
 
   443 //     std::cout<<"Itt a primal: "<<lpx_get_prim_stat(lp)<<std::endl;
 
   445     switch (lpx_get_dual_stat(lp)) {
 
   446     case LPX_D_UNDEF://Undefined (no solve has been run yet)
 
   448     case LPX_D_NOFEAS://There is no dual feasible solution 
 
   449 //    case LPX_D_INFEAS://Infeasible 
 
   451     case LPX_D_FEAS://Feasible    
 
   452       switch (lpx_get_status(lp)) {
 
   461       return UNDEFINED; //to avoid gcc warning
 
   466   LpGlpk::ProblemTypes LpGlpk::_getProblemType()
 
   468       //int stat=  lpx_get_status(lp);
 
   469     int statp=  lpx_get_prim_stat(lp);
 
   470     int statd=  lpx_get_dual_stat(lp);
 
   471     if (statp==LPX_P_FEAS && statd==LPX_D_FEAS)
 
   472 	return PRIMAL_DUAL_FEASIBLE;
 
   473     if (statp==LPX_P_FEAS && statd==LPX_D_NOFEAS)
 
   474 	return PRIMAL_FEASIBLE_DUAL_INFEASIBLE;
 
   475     if (statp==LPX_P_NOFEAS && statd==LPX_D_FEAS)
 
   476 	return PRIMAL_INFEASIBLE_DUAL_FEASIBLE;
 
   477     if (statp==LPX_P_NOFEAS && statd==LPX_D_NOFEAS)
 
   478 	return PRIMAL_DUAL_INFEASIBLE;
 
   483   void LpGlpk::_setMax()
 
   485     lpx_set_obj_dir(lp, LPX_MAX);
 
   488   void LpGlpk::_setMin()
 
   490     lpx_set_obj_dir(lp, LPX_MIN);
 
   494   void LpGlpk::messageLevel(int m)
 
   496     lpx_set_int_parm(lp, LPX_K_MSGLEV, m);
 
   499   void LpGlpk::presolver(bool b)
 
   501     lpx_set_int_parm(lp, LPX_K_PRESOL, b);
 
   505 } //END OF NAMESPACE LEMON
 
   507 #endif //LEMON_LP_GLPK_CC