MIP support added (by Jano, the Great).
authorathos
Mon, 17 Jul 2006 09:00:21 +0000
changeset 2144cd8897f67c26
parent 2143 4b3191b4970b
child 2145 73e0c8207e11
MIP support added (by Jano, the Great).
lemon/Makefile.am
lemon/lp.h
lemon/lp_base.h
lemon/lp_glpk.h
lemon/mip_glpk.cc
lemon/mip_glpk.h
test/Makefile.am
test/mip_test.cc
     1.1 --- a/lemon/Makefile.am	Mon Jul 17 07:30:56 2006 +0000
     1.2 +++ b/lemon/Makefile.am	Mon Jul 17 09:00:21 2006 +0000
     1.3 @@ -19,6 +19,7 @@
     1.4  
     1.5  if HAVE_GLPK
     1.6  lemon_libemon_la_SOURCES += lemon/lp_glpk.cc
     1.7 +lemon_libemon_la_SOURCES += lemon/mip_glpk.cc
     1.8  endif
     1.9  
    1.10  if HAVE_CPLEX
     2.1 --- a/lemon/lp.h	Mon Jul 17 07:30:56 2006 +0000
     2.2 +++ b/lemon/lp.h	Mon Jul 17 09:00:21 2006 +0000
     2.3 @@ -23,6 +23,7 @@
     2.4  
     2.5  #ifdef HAVE_GLPK
     2.6  #include <lemon/lp_glpk.h>
     2.7 +#include <lemon/mip_glpk.h>
     2.8  #elif HAVE_CPLEX
     2.9  #include <lemon/lp_cplex.h>
    2.10  #endif
    2.11 @@ -54,10 +55,19 @@
    2.12    ///
    2.13    ///Currently, the possible values are "GLPK" or "CPLEX"
    2.14    const char default_solver_name[]="SOLVER";  
    2.15 +
    2.16 +  ///The default ILP solver.
    2.17 +
    2.18 +  ///The default ILP solver.
    2.19 +  ///\ingroup gen_opt_group
    2.20 +  ///
    2.21 +  ///Currently, it is either \c LpGlpk or \c LpCplex
    2.22 +  typedef MipGlpk Mip;
    2.23  #else
    2.24  #ifdef HAVE_GLPK
    2.25  #define DEFAULT_LP GLPK
    2.26    typedef LpGlpk Lp;
    2.27 +  typedef MipGlpk Mip;
    2.28    const char default_solver_name[]="GLPK";
    2.29  #elif HAVE_CPLEX
    2.30  #define DEFAULT_LP CPLEX
     3.1 --- a/lemon/lp_base.h	Mon Jul 17 07:30:56 2006 +0000
     3.2 +++ b/lemon/lp_base.h	Mon Jul 17 09:00:21 2006 +0000
     3.3 @@ -175,6 +175,7 @@
     3.4      protected:
     3.5        int id;
     3.6        friend class LpSolverBase;
     3.7 +      friend class MipSolverBase;
     3.8      public:
     3.9        typedef Value ExprValue;
    3.10        typedef True LpSolverCol;
    3.11 @@ -1156,7 +1157,33 @@
    3.12      
    3.13    };  
    3.14  
    3.15 -  ///\e
    3.16 +
    3.17 +  ///Common base class for ILP solvers
    3.18 +  ///\todo Much more docs
    3.19 +  ///\ingroup gen_opt_group
    3.20 +  class MipSolverBase : virtual public LpSolverBase{
    3.21 +  public:
    3.22 +
    3.23 +    ///Set the type of the given Col to integer or remove that property.
    3.24 +    ///
    3.25 +    ///Set the type of the given Col to integer or remove that property.
    3.26 +    void integer(Col c, bool enable) {
    3.27 +      _integer(cols.floatingId(c.id),enable);
    3.28 +    }
    3.29 +
    3.30 +    ///Gives back the type of the column.
    3.31 +    ///
    3.32 +    ///Gives back the type of the column.
    3.33 +    ///\return true if the column has integer type and false if not.
    3.34 +    bool integer(Col c){
    3.35 +      return _integer(cols.floatingId(c.id));
    3.36 +    }
    3.37 +
    3.38 +  protected:
    3.39 +
    3.40 +    virtual bool _integer(int col) = 0;
    3.41 +    virtual void _integer(int col, bool enable) = 0;
    3.42 +  };
    3.43    
    3.44    ///\relates LpSolverBase::Expr
    3.45    ///
     4.1 --- a/lemon/lp_glpk.h	Mon Jul 17 07:30:56 2006 +0000
     4.2 +++ b/lemon/lp_glpk.h	Mon Jul 17 09:00:21 2006 +0000
     4.3 @@ -35,7 +35,7 @@
     4.4    /// 
     4.5    /// This class implements an interface for the GLPK LP solver.
     4.6    ///\ingroup gen_opt_group
     4.7 -  class LpGlpk : public LpSolverBase {
     4.8 +  class LpGlpk : virtual public LpSolverBase {
     4.9    protected:
    4.10      LPX* lp;
    4.11      
     5.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     5.2 +++ b/lemon/mip_glpk.cc	Mon Jul 17 09:00:21 2006 +0000
     5.3 @@ -0,0 +1,72 @@
     5.4 +/* -*- C++ -*-
     5.5 + *
     5.6 + * This file is a part of LEMON, a generic C++ optimization library
     5.7 + *
     5.8 + * Copyright (C) 2003-2006
     5.9 + * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
    5.10 + * (Egervary Research Group on Combinatorial Optimization, EGRES).
    5.11 + *
    5.12 + * Permission to use, modify and distribute this software is granted
    5.13 + * provided that this copyright notice appears in all copies. For
    5.14 + * precise terms see the accompanying LICENSE file.
    5.15 + *
    5.16 + * This software is provided "AS IS" with no warranty of any kind,
    5.17 + * express or implied, and with no claim as to its suitability for any
    5.18 + * purpose.
    5.19 + *
    5.20 + */
    5.21 +
    5.22 +#ifndef LEMON_ILP_GLPK_CC
    5.23 +#define LEMON_ILP_GLPK_CC
    5.24 +
    5.25 +///\file
    5.26 +///\brief Implementation of the LEMON-GLPK lp solver interface.
    5.27 +
    5.28 +#include <lemon/mip_glpk.h>
    5.29 +
    5.30 +namespace lemon {
    5.31 +  
    5.32 +  MipGlpk::MipGlpk() {
    5.33 +    lpx_set_class(lp,LPX_MIP);
    5.34 +  }
    5.35 +  
    5.36 +  void MipGlpk::_integer(int i, bool enable){
    5.37 +    if(enable){
    5.38 +      lpx_set_col_kind(lp,i,LPX_IV);
    5.39 +    }else{
    5.40 +      lpx_set_col_kind(lp,i,LPX_CV);
    5.41 +    }
    5.42 +  }
    5.43 +  
    5.44 +  bool MipGlpk::_integer(int i){
    5.45 +    if(LPX_IV == lpx_get_col_kind(lp,i)){
    5.46 +      return true;
    5.47 +    }
    5.48 +    return false;
    5.49 +  }
    5.50 +  
    5.51 +  LpGlpk::SolveExitStatus MipGlpk::_solve(){
    5.52 +    int result = lpx_simplex(lp);
    5.53 +    result = lpx_integer(lp);
    5.54 +    switch (result){
    5.55 +      case LPX_E_OBJLL:
    5.56 +      case LPX_E_OBJUL:
    5.57 +      case LPX_E_ITLIM:
    5.58 +      case LPX_E_TMLIM:
    5.59 +      case LPX_E_OK:
    5.60 +        return SOLVED;
    5.61 +      default:
    5.62 +        return UNSOLVED;
    5.63 +    }
    5.64 +  }
    5.65 +  
    5.66 +  MipGlpk::Value MipGlpk::_getPrimal(int i){
    5.67 +    return lpx_mip_col_val(lp,i);
    5.68 +  }
    5.69 +  
    5.70 +  MipGlpk::Value MipGlpk::_getPrimalValue(){
    5.71 +    return lpx_mip_obj_val(lp);
    5.72 +  }
    5.73 +} //END OG NAMESPACE LEMON
    5.74 +
    5.75 +#endif
     6.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     6.2 +++ b/lemon/mip_glpk.h	Mon Jul 17 09:00:21 2006 +0000
     6.3 @@ -0,0 +1,58 @@
     6.4 +/* -*- C++ -*-
     6.5 + *
     6.6 + * This file is a part of LEMON, a generic C++ optimization library
     6.7 + *
     6.8 + * Copyright (C) 2003-2006
     6.9 + * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
    6.10 + * (Egervary Research Group on Combinatorial Optimization, EGRES).
    6.11 + *
    6.12 + * Permission to use, modify and distribute this software is granted
    6.13 + * provided that this copyright notice appears in all copies. For
    6.14 + * precise terms see the accompanying LICENSE file.
    6.15 + *
    6.16 + * This software is provided "AS IS" with no warranty of any kind,
    6.17 + * express or implied, and with no claim as to its suitability for any
    6.18 + * purpose.
    6.19 + *
    6.20 + */
    6.21 +
    6.22 +#ifndef LEMON_ILP_GLPK_H
    6.23 +#define LEMON_ILP_GLPK_H
    6.24 +
    6.25 +///\file
    6.26 +///\brief Header of the LEMON-GLPK lp solver interface.
    6.27 +///\ingroup gen_opt_group
    6.28 +
    6.29 +
    6.30 +#include <lemon/lp_glpk.h>
    6.31 +
    6.32 +namespace lemon {
    6.33 +  /// \brief Interface for the GLPK ILP solver
    6.34 +  /// 
    6.35 +  /// This class implements an interface for the GLPK ILP solver.
    6.36 +  ///\ingroup gen_opt_group
    6.37 +  class MipGlpk : public MipSolverBase, public LpGlpk{
    6.38 +  
    6.39 +  public:
    6.40 +  
    6.41 +    typedef MipSolverBase ParentMip;
    6.42 +    typedef LpGlpk ParentLp;
    6.43 +    
    6.44 +    MipGlpk();
    6.45 +    //~MipGlpk();
    6.46 +    
    6.47 +    
    6.48 +    
    6.49 +  protected:
    6.50 +  
    6.51 +    virtual void _integer(int c, bool enable);
    6.52 +    virtual bool _integer(int c);
    6.53 +    
    6.54 +    virtual LpGlpk::SolveExitStatus _solve();
    6.55 +    virtual ParentLp::Value _getPrimal(int i);
    6.56 +    virtual ParentLp::Value _getPrimalValue();
    6.57 +  };
    6.58 +
    6.59 +} //END OF NAMESPACE LEMON
    6.60 +
    6.61 +#endif // END OF LEMON_ILP_GLPK_H
     7.1 --- a/test/Makefile.am	Mon Jul 17 07:30:56 2006 +0000
     7.2 +++ b/test/Makefile.am	Mon Jul 17 09:00:21 2006 +0000
     7.3 @@ -28,6 +28,7 @@
     7.4  	test/matrix_maps_test \
     7.5  	test/max_matching_test \
     7.6  	test/min_cost_flow_test \
     7.7 +	test/mip_test \
     7.8  	test/path_test \
     7.9  	test/polynomial_test \
    7.10  	test/preflow_test \
    7.11 @@ -70,6 +71,7 @@
    7.12  test_matrix_maps_test_SOURCES = test/matrix_maps_test.cc
    7.13  test_max_matching_test_SOURCES = test/max_matching_test.cc
    7.14  test_min_cost_flow_test_SOURCES = test/min_cost_flow_test.cc
    7.15 +test_mip_test_SOURCES = test/mip_test.cc
    7.16  test_path_test_SOURCES = test/path_test.cc
    7.17  test_polynomial_test_SOURCES = test/polynomial_test.cc
    7.18  test_preflow_test_SOURCES = test/preflow_test.cc
     8.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     8.2 +++ b/test/mip_test.cc	Mon Jul 17 09:00:21 2006 +0000
     8.3 @@ -0,0 +1,50 @@
     8.4 +#include <lemon/lp.h>
     8.5 +//#include <lemon/ilp_glpk.h>
     8.6 +
     8.7 +using namespace lemon;
     8.8 +
     8.9 +int main(){
    8.10 +
    8.11 +  //MipGlpk ilp;
    8.12 +
    8.13 +   Mip ilp;
    8.14 +
    8.15 +    
    8.16 +  typedef Mip::Row Row;
    8.17 +  typedef Mip::Col Col;
    8.18 +  
    8.19 +  ilp.max();
    8.20 +  
    8.21 +  Col x1 = ilp.addCol();
    8.22 +  Col x2 = ilp.addCol();
    8.23 +  Col x3 = ilp.addCol();
    8.24 +  
    8.25 +  ilp.integer(x1,true);
    8.26 +  ilp.integer(x2,true);
    8.27 +  ilp.integer(x3,true);
    8.28 +  
    8.29 +  ilp.addRow(x1+x2+x3 <=100);  
    8.30 +  ilp.addRow(10*x1+4*x2+5*x3<=600);  
    8.31 +  ilp.addRow(2*x1+2*x2+6*x3<=300); 
    8.32 +  
    8.33 +  ilp.colLowerBound(x1, 0);
    8.34 +  ilp.colLowerBound(x2, 0);
    8.35 +  ilp.colLowerBound(x3, 0);
    8.36 +  //Objective function
    8.37 +  ilp.setObj(10*x1+6*x2+4*x3);
    8.38 +  
    8.39 +  //Call the routine of the underlying LP solver
    8.40 +  ilp.solve();
    8.41 +  
    8.42 +  //Print results
    8.43 +  if (ilp.primalStatus()==LpSolverBase::OPTIMAL){
    8.44 +    std::cout<<"Optimal solution found!"<<std::endl;
    8.45 +    printf("optimum value = %g; x1 = %g; x2 = %g; x3 = %g\n", 
    8.46 +           ilp.primalValue(), 
    8.47 +           ilp.primal(x1), ilp.primal(x2), ilp.primal(x3));
    8.48 +  }
    8.49 +  else{
    8.50 +    std::cout<<"Optimal solution not found!"<<std::endl;
    8.51 +  }
    8.52 +
    8.53 +}