1.1 --- a/src/demo/Makefile.am Fri Apr 22 16:20:12 2005 +0000
1.2 +++ b/src/demo/Makefile.am Fri Apr 22 17:47:01 2005 +0000
1.3 @@ -1,6 +1,17 @@
1.4 AM_CPPFLAGS = -I$(top_srcdir)/src
1.5 LDADD = $(top_builddir)/src/lemon/libemon.la
1.6
1.7 +if HAVE_GLPK
1.8 +LP_CFLAGS = $(GLPK_CFLAGS) -DHAVE_GLPK
1.9 +LP_LIBS = $(GLPK_LIBS)
1.10 +else !HAVE_GLPK
1.11 +if HAVE_CPLEX
1.12 +LP_CFLAGS = $(CPLEX_CFLAGS) -DHAVE_CPLEX
1.13 +LP_LIBS = $(CPLEX_LIBS)
1.14 +endif HAVE_CPLEX
1.15 +endif !HAVE_GLPK
1.16 +
1.17 +
1.18 EXTRA_DIST = sub_graph_wrapper_demo.dim
1.19
1.20 noinst_PROGRAMS = \
1.21 @@ -12,7 +23,12 @@
1.22
1.23 if HAVE_GLPK
1.24 noinst_PROGRAMS += lp_demo lp_maxflow_demo
1.25 -endif
1.26 +else !HAVE_GLPK
1.27 +if HAVE_CPLEX
1.28 +noinst_PROGRAMS += lp_demo lp_maxflow_demo
1.29 +endif HAVE_CPLEX
1.30 +endif !HAVE_GLPK
1.31 +
1.32
1.33 dim_to_dot_SOURCES = dim_to_dot.cc
1.34
1.35 @@ -27,9 +43,9 @@
1.36 tight_edge_filter_map.h
1.37
1.38 lp_demo_SOURCES = lp_demo.cc
1.39 -lp_demo_CXXFLAGS = $(GLPK_CFLAGS)
1.40 -lp_demo_LDFLAGS = $(GLPK_LIBS)
1.41 +lp_demo_CXXFLAGS = $(LP_CFLAGS)
1.42 +lp_demo_LDFLAGS = $(LP_LIBS)
1.43
1.44 lp_maxflow_demo_SOURCES = lp_maxflow_demo.cc
1.45 -lp_maxflow_demo_CXXFLAGS = $(GLPK_CFLAGS)
1.46 -lp_maxflow_demo_LDFLAGS = $(GLPK_LIBS)
1.47 +lp_maxflow_demo_CXXFLAGS = $(LP_CFLAGS)
1.48 +lp_maxflow_demo_LDFLAGS = $(LP_LIBS)
2.1 --- a/src/demo/lp_demo.cc Fri Apr 22 16:20:12 2005 +0000
2.2 +++ b/src/demo/lp_demo.cc Fri Apr 22 17:47:01 2005 +0000
2.3 @@ -1,14 +1,27 @@
2.4 #include <iostream>
2.5 +
2.6 +
2.7 +#ifdef HAVE_GLPK
2.8 #include <lemon/lp_glpk.h>
2.9 +#elif HAVE_CPLEX
2.10 +#include <lemon/lp_cplex.h>
2.11 +#endif
2.12 +
2.13 using namespace lemon;
2.14
2.15 +#ifdef HAVE_GLPK
2.16 +typedef LpGlpk LpDefault;
2.17 +#elif HAVE_CPLEX
2.18 +typedef LpCplex LpDefault;
2.19 +#endif
2.20 +
2.21 int main()
2.22 {
2.23 //The following example is taken from the documentation of the GLPK library.
2.24 //See it in the GLPK reference manual and among the GLPK sample files (sample.c)
2.25 - LpGlpk lp;
2.26 - typedef LpGlpk::Row Row;
2.27 - typedef LpGlpk::Col Col;
2.28 + LpDefault lp;
2.29 + typedef LpDefault::Row Row;
2.30 + typedef LpDefault::Col Col;
2.31
2.32 lp.max();
2.33
3.1 --- a/src/demo/lp_maxflow_demo.cc Fri Apr 22 16:20:12 2005 +0000
3.2 +++ b/src/demo/lp_maxflow_demo.cc Fri Apr 22 17:47:01 2005 +0000
3.3 @@ -1,13 +1,26 @@
3.4 -#include<lemon/lp_glpk.h>
3.5 #include<lemon/graph_reader.h>
3.6 #include<lemon/list_graph.h>
3.7
3.8 +
3.9 +#ifdef HAVE_GLPK
3.10 +#include <lemon/lp_glpk.h>
3.11 +#elif HAVE_CPLEX
3.12 +#include <lemon/lp_cplex.h>
3.13 +#endif
3.14 +
3.15 using namespace lemon;
3.16
3.17 +#ifdef HAVE_GLPK
3.18 +typedef LpGlpk LpDefault;
3.19 +#elif HAVE_CPLEX
3.20 +typedef LpCplex LpDefault;
3.21 +#endif
3.22 +
3.23 +
3.24 template<class G,class C>
3.25 double maxFlow(const G &g,const C &cap,typename G::Node s,typename G::Node t)
3.26 {
3.27 - LpGlpk lp;
3.28 + LpDefault lp;
3.29
3.30 typedef G Graph;
3.31 typedef typename G::Node Node;
3.32 @@ -17,7 +30,7 @@
3.33 typedef typename G::OutEdgeIt OutEdgeIt;
3.34 typedef typename G::InEdgeIt InEdgeIt;
3.35
3.36 - typename G::template EdgeMap<LpGlpk::Col> x(g);
3.37 + typename G::template EdgeMap<LpDefault::Col> x(g);
3.38 lp.addColSet(x);
3.39
3.40 for(EdgeIt e(g);e!=INVALID;++e) {
3.41 @@ -26,22 +39,23 @@
3.42 }
3.43
3.44 for(NodeIt n(g);n!=INVALID;++n) if(n!=s&&n!=t) {
3.45 - LpGlpk::Expr ex;
3.46 + LpDefault::Expr ex;
3.47 for(InEdgeIt e(g,n);e!=INVALID;++e) ex+=x[e];
3.48 for(OutEdgeIt e(g,n);e!=INVALID;++e) ex-=x[e];
3.49 lp.addRow(ex==0);
3.50 }
3.51 {
3.52 - LpGlpk::Expr ex;
3.53 + LpDefault::Expr ex;
3.54 for(InEdgeIt e(g,t);e!=INVALID;++e) ex+=x[e];
3.55 for(OutEdgeIt e(g,t);e!=INVALID;++e) ex-=x[e];
3.56 lp.setObj(ex);
3.57 }
3.58 lp.max();
3.59
3.60 +#ifdef HAVE_GLPK
3.61 lp.presolver(true);
3.62 -
3.63 lp.messageLevel(3);
3.64 +#endif
3.65
3.66 lp.solve();
3.67
4.1 --- a/src/lemon/Makefile.am Fri Apr 22 16:20:12 2005 +0000
4.2 +++ b/src/lemon/Makefile.am Fri Apr 22 17:47:01 2005 +0000
4.3 @@ -15,6 +15,12 @@
4.4 libemon_la_LDFLAGS = $(GLPK_LIBS)
4.5 endif
4.6
4.7 +if HAVE_CPLEX
4.8 +libemon_la_SOURCES += lp_cplex.cc
4.9 +libemon_la_CXXFLAGS = $(CPLEX_CFLAGS)
4.10 +libemon_la_LDFLAGS = $(CPLEX_LIBS)
4.11 +endif
4.12 +
4.13 nobase_pkginclude_HEADERS = \
4.14 bezier.h \
4.15 bfs.h \
4.16 @@ -32,6 +38,7 @@
4.17 kruskal.h \
4.18 list_graph.h \
4.19 lp_base.h \
4.20 + lp_cplex.h \
4.21 lp_glpk.h \
4.22 lp_skeleton.h \
4.23 maps.h \
5.1 --- a/src/lemon/lp_base.h Fri Apr 22 16:20:12 2005 +0000
5.2 +++ b/src/lemon/lp_base.h Fri Apr 22 17:47:01 2005 +0000
5.3 @@ -464,7 +464,7 @@
5.4
5.5 ///Creates a new LP problem
5.6 LpSolverBase &newLp() {return _newLp();}
5.7 - ///Make a copy of the LP problem
5.8 + ///Makes a copy of the LP problem
5.9 LpSolverBase ©Lp() {return _copyLp();}
5.10
5.11 ///\name Build up and modify of the LP
6.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
6.2 +++ b/src/lemon/lp_cplex.cc Fri Apr 22 17:47:01 2005 +0000
6.3 @@ -0,0 +1,309 @@
6.4 +/* -*- C++ -*-
6.5 + * src/lemon/lp_cplex.cc
6.6 + * - Part of LEMON, a generic C++ optimization library
6.7 + *
6.8 + * Copyright (C) 2005 Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
6.9 + * (Egervary Research Group on Combinatorial Optimization, EGRES).
6.10 + *
6.11 + * Permission to use, modify and distribute this software is granted
6.12 + * provided that this copyright notice appears in all copies. For
6.13 + * precise terms see the accompanying LICENSE file.
6.14 + *
6.15 + * This software is provided "AS IS" with no warranty of any kind,
6.16 + * express or implied, and with no claim as to its suitability for any
6.17 + * purpose.
6.18 + *
6.19 + */
6.20 +
6.21 +#include"lp_cplex.h"
6.22 +
6.23 +///\file
6.24 +///\brief Implementation of the LEMON-CPLEX lp solver interface.
6.25 +namespace lemon {
6.26 +
6.27 + LpCplex::LpCplex() : LpSolverBase() {
6.28 + env = NULL;
6.29 + lp = NULL;
6.30 + env = CPXopenCPLEXdevelop(&status);
6.31 +// if (Env == NULL)
6.32 +// {
6.33 +// fprintf(stderr,"A CPLEX környezet megnyitása sikertelen.\n");
6.34 +// CPXgeterrorstring(Env, Status, ErrorMsg);
6.35 +// fprintf(stderr,"%s",ErrorMsg);
6.36 +// goto Terminate;
6.37 +// }
6.38 +
6.39 + // *** A problema létrehozása ***
6.40 + lp = CPXcreateprob(env, &status, "LP problem");
6.41 +
6.42 + // if (Problem == NULL)
6.43 +// {
6.44 +// fprintf(stderr,"Az LP létrehozása sikertelen");
6.45 +// goto Terminate;
6.46 +// }
6.47 +
6.48 + }
6.49 +
6.50 + LpCplex::~LpCplex() {
6.51 + status = CPXfreeprob(env,&lp);
6.52 + // if (Status != 0)
6.53 + // {
6.54 +// fprintf(stderr,"A CPLEX feladat törlése sikertelen.\n");
6.55 +// CPXgeterrorstring(Env, Status, ErrorMsg);
6.56 +// fprintf(stderr,"%s",ErrorMsg);
6.57 +// goto Terminate;
6.58 +// }
6.59 +
6.60 + status = CPXcloseCPLEX(&env);
6.61 + // if (Status != 0)
6.62 + // {
6.63 + // fprintf(stderr,"A CPLEX környezet bezárása sikertelen.\n");
6.64 +// CPXgeterrorstring(Env, Status, ErrorMsg);
6.65 +// fprintf(stderr,"%s",ErrorMsg);
6.66 +// goto Terminate;
6.67 +// }
6.68 +
6.69 + }
6.70 +
6.71 + LpSolverBase &LpCplex::_newLp() {return *(LpSolverBase*)0;}
6.72 + LpSolverBase &LpCplex::_copyLp() {return *(LpSolverBase*)0;}
6.73 +
6.74 + int LpCplex::_addCol()
6.75 + {
6.76 + int i = CPXgetnumcols (env, lp);
6.77 + Value lb[1],ub[1];
6.78 + lb[0]=-INF;//-CPX_INFBOUND;
6.79 + ub[0]=INF;//CPX_INFBOUND;
6.80 + status = CPXnewcols (env, lp, 1, NULL, lb, ub, NULL, NULL);
6.81 + return i;
6.82 + }
6.83 +
6.84 + int LpCplex::_addRow()
6.85 + {
6.86 + //We want a row that is not constrained
6.87 + char sense[1];
6.88 + sense[0]='L';//<= constraint
6.89 + Value rhs[1];
6.90 + rhs[0]=INF;
6.91 + int i = CPXgetnumrows (env, lp);
6.92 + status = CPXnewrows (env, lp, 1, rhs, sense, NULL, NULL);
6.93 + return i;
6.94 + }
6.95 +
6.96 + ///\warning Data at index 0 is ignored in the arrays.
6.97 + void LpCplex::_setRowCoeffs(int i,
6.98 + int length,
6.99 + int const * indices,
6.100 + Value const * values )
6.101 + {
6.102 + int rowlist[length+1];
6.103 + int* p=rowlist;
6.104 + for (int k=1;k<=length;++k){
6.105 + rowlist[k]=i;
6.106 + }
6.107 + status = CPXchgcoeflist(env, lp,
6.108 + length,
6.109 + p+1,
6.110 + const_cast<int * >(indices+1),
6.111 + const_cast<Value * >(values+1));
6.112 + }
6.113 +
6.114 + void LpCplex::_setColCoeffs(int i,
6.115 + int length,
6.116 + int const * indices,
6.117 + Value const * values)
6.118 + {
6.119 + int collist[length+1];
6.120 + int* p=collist;
6.121 + for (int k=1;k<=length;++k){
6.122 + collist[k]=i;
6.123 + }
6.124 + status = CPXchgcoeflist(env, lp,
6.125 + length,
6.126 + const_cast<int * >(indices+1),
6.127 + p+1,
6.128 + const_cast<Value * >(values+1));
6.129 + }
6.130 +
6.131 + void LpCplex::_setColLowerBound(int i, Value value)
6.132 + {
6.133 + int indices[1];
6.134 + indices[0]=i;
6.135 + char lu[1];
6.136 + lu[0]='L';
6.137 + Value bd[1];
6.138 + bd[0]=value;
6.139 + status = CPXchgbds (env, lp, 1, indices, lu, bd);
6.140 +
6.141 + }
6.142 +
6.143 + void LpCplex::_setColUpperBound(int i, Value value)
6.144 + {
6.145 + int indices[1];
6.146 + indices[0]=i;
6.147 + char lu[1];
6.148 + lu[0]='U';
6.149 + Value bd[1];
6.150 + bd[0]=value;
6.151 + status = CPXchgbds (env, lp, 1, indices, lu, bd);
6.152 + }
6.153 +
6.154 + //This will be easier to implement
6.155 + void LpCplex::_setRowBounds(int i, Value lb, Value ub)
6.156 + {
6.157 + //Bad parameter
6.158 + if (lb==INF || ub==-INF) {
6.159 + //FIXME error
6.160 + }
6.161 +
6.162 + int cnt=1;
6.163 + int indices[1];
6.164 + indices[0]=i;
6.165 + char sense[1];
6.166 +
6.167 + if (lb==-INF){
6.168 + sense[0]='L';
6.169 + CPXchgsense (env, lp, cnt, indices, sense);
6.170 + CPXchgcoef (env, lp, i, -1, ub);
6.171 + }
6.172 + else{
6.173 + if (ub==INF){
6.174 + sense[0]='G';
6.175 + CPXchgsense (env, lp, cnt, indices, sense);
6.176 + CPXchgcoef (env, lp, i, -1, lb);
6.177 + }
6.178 + else{
6.179 + if (lb == ub){
6.180 + sense[0]='E';
6.181 + CPXchgsense (env, lp, cnt, indices, sense);
6.182 + CPXchgcoef (env, lp, i, -1, lb);
6.183 + }
6.184 + else{
6.185 + sense[0]='R';
6.186 + CPXchgsense (env, lp, cnt, indices, sense);
6.187 + CPXchgcoef (env, lp, i, -1, lb);
6.188 + CPXchgcoef (env, lp, i, -2, ub-lb);
6.189 + }
6.190 + }
6.191 + }
6.192 + }
6.193 +
6.194 + void LpCplex::_setRowLowerBound(int i, Value value)
6.195 + {
6.196 + //Not implemented, obsolete
6.197 + }
6.198 +
6.199 + void LpCplex::_setRowUpperBound(int i, Value value)
6.200 + {
6.201 + //Not implemented, obsolete
6.202 +// //TODO Ezt kell meg megirni
6.203 +// //type of the problem
6.204 +// char sense[1];
6.205 +// status = CPXgetsense (env, lp, sense, i, i);
6.206 +// Value rhs[1];
6.207 +// status = CPXgetrhs (env, lp, rhs, i, i);
6.208 +
6.209 +// switch (sense[0]) {
6.210 +// case 'L'://<= constraint
6.211 +// break;
6.212 +// case 'E'://= constraint
6.213 +// break;
6.214 +// case 'G'://>= constraint
6.215 +// break;
6.216 +// case 'R'://ranged constraint
6.217 +// break;
6.218 +// default: ;
6.219 +// //FIXME error
6.220 +// }
6.221 +
6.222 +// status = CPXchgcoef (env, lp, i, -2, value_rng);
6.223 + }
6.224 +
6.225 + void LpCplex::_setObjCoeff(int i, Value obj_coef)
6.226 + {
6.227 + CPXchgcoef (env, lp, -1, i, obj_coef);
6.228 + }
6.229 +
6.230 + void LpCplex::_clearObj()
6.231 + {
6.232 + for (int i=0;i< CPXgetnumcols (env, lp);++i){
6.233 + CPXchgcoef (env, lp, -1, i, 0);
6.234 + }
6.235 +
6.236 + }
6.237 +
6.238 + LpCplex::SolveExitStatus LpCplex::_solve()
6.239 + {
6.240 +
6.241 + status = CPXlpopt (env, lp);
6.242 + if (status == 0){
6.243 + return SOLVED;
6.244 + }
6.245 + else{
6.246 + return UNSOLVED;
6.247 + }
6.248 +// int i= lpx_simplex(lp);
6.249 +// switch (i) {
6.250 +// case LPX_E_OK:
6.251 +// return SOLVED;
6.252 +// break;
6.253 +// default:
6.254 +// return UNSOLVED;
6.255 +// }
6.256 + }
6.257 +
6.258 + LpCplex::SolutionStatus LpCplex::_getPrimalStatus()
6.259 + {
6.260 + //Unimplemented
6.261 + return OPTIMAL;
6.262 +// int stat= lpx_get_status(lp);
6.263 +// switch (stat) {
6.264 +// case LPX_UNDEF://Undefined (no solve has been run yet)
6.265 +// return UNDEFINED;
6.266 +// break;
6.267 +// case LPX_NOFEAS://There is no feasible solution (primal, I guess)
6.268 +// case LPX_INFEAS://Infeasible
6.269 +// return INFEASIBLE;
6.270 +// break;
6.271 +// case LPX_UNBND://Unbounded
6.272 +// return INFINITE;
6.273 +// break;
6.274 +// case LPX_FEAS://Feasible
6.275 +// return FEASIBLE;
6.276 +// break;
6.277 +// case LPX_OPT://Feasible
6.278 +// return OPTIMAL;
6.279 +// break;
6.280 +// default:
6.281 +// return UNDEFINED; //to avoid gcc warning
6.282 +// //FIXME error
6.283 +// }
6.284 + }
6.285 +
6.286 + LpCplex::Value LpCplex::_getPrimal(int i)
6.287 + {
6.288 + Value x;
6.289 + CPXgetx (env, lp, &x, i, i);
6.290 + return x;
6.291 + }
6.292 +
6.293 + LpCplex::Value LpCplex::_getPrimalValue()
6.294 + {
6.295 + //Unimplemented
6.296 + return 0;
6.297 + }
6.298 +
6.299 +
6.300 +
6.301 +
6.302 + void LpCplex::_setMax()
6.303 + {
6.304 + CPXchgobjsen (env, lp, CPX_MAX);
6.305 + }
6.306 + void LpCplex::_setMin()
6.307 + {
6.308 + CPXchgobjsen (env, lp, CPX_MIN);
6.309 + }
6.310 +
6.311 +} //namespace lemon
6.312 +
7.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
7.2 +++ b/src/lemon/lp_cplex.h Fri Apr 22 17:47:01 2005 +0000
7.3 @@ -0,0 +1,108 @@
7.4 +/* -*- C++ -*-
7.5 + * src/lemon/lp_cplex.h - Part of LEMON, a generic C++ optimization library
7.6 + *
7.7 + * Copyright (C) 2005 Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
7.8 + * (Egervary Research Group on Combinatorial Optimization, EGRES).
7.9 + *
7.10 + * Permission to use, modify and distribute this software is granted
7.11 + * provided that this copyright notice appears in all copies. For
7.12 + * precise terms see the accompanying LICENSE file.
7.13 + *
7.14 + * This software is provided "AS IS" with no warranty of any kind,
7.15 + * express or implied, and with no claim as to its suitability for any
7.16 + * purpose.
7.17 + *
7.18 + */
7.19 +
7.20 +#ifndef LEMON_LP_CPLEX_H
7.21 +#define LEMON_LP_CPLEX_H
7.22 +
7.23 +///\file
7.24 +///\brief Header of the LEMON-CPLEX lp solver interface.
7.25 +
7.26 +#include <lemon/lp_base.h>
7.27 +extern "C" {
7.28 +#include <ilcplex/cplex.h>
7.29 +}
7.30 +
7.31 +namespace lemon {
7.32 +
7.33 +
7.34 + /// \brief Wrapper for GLPK solver
7.35 + ///
7.36 + /// This class implements a lemon wrapper for GLPK.
7.37 + class LpCplex : public LpSolverBase {
7.38 +
7.39 + public:
7.40 +
7.41 + typedef LpSolverBase Parent;
7.42 +
7.43 + /// \e
7.44 + int status;
7.45 + CPXENVptr env;
7.46 + CPXLPptr lp;
7.47 +
7.48 +
7.49 + /// \e
7.50 + LpCplex();
7.51 + /// \e
7.52 + ~LpCplex();
7.53 +
7.54 + protected:
7.55 + virtual LpSolverBase &_newLp();
7.56 + virtual LpSolverBase &_copyLp();
7.57 +
7.58 + virtual int _addCol();
7.59 + virtual int _addRow();
7.60 + virtual void _setRowCoeffs(int i,
7.61 + int length,
7.62 + const int * indices,
7.63 + const Value * values );
7.64 + virtual void _setColCoeffs(int i,
7.65 + int length,
7.66 + const int * indices,
7.67 + const Value * values);
7.68 + virtual void _setColLowerBound(int i, Value value);
7.69 + virtual void _setColUpperBound(int i, Value value);
7.70 + virtual void _setRowLowerBound(int i, Value value);
7.71 + virtual void _setRowUpperBound(int i, Value value);
7.72 + virtual void _setRowBounds(int i, Value lower, Value upper);
7.73 + virtual void _setObjCoeff(int i, Value obj_coef);
7.74 + virtual void _clearObj();
7.75 + ///\e
7.76 +
7.77 + ///\bug Unimplemented
7.78 + ///
7.79 + virtual SolveExitStatus _solve();
7.80 + ///\e
7.81 +
7.82 + ///\bug Unimplemented
7.83 + ///
7.84 + virtual Value _getPrimal(int i);
7.85 + ///\e
7.86 +
7.87 + ///\bug Unimplemented
7.88 + ///
7.89 + virtual Value _getPrimalValue();
7.90 + ///\e
7.91 +
7.92 + ///\bug Unimplemented
7.93 + ///
7.94 + virtual SolutionStatus _getPrimalStatus();
7.95 +
7.96 + ///\e
7.97 +
7.98 + ///\bug Unimplemented
7.99 + ///
7.100 + virtual void _setMax();
7.101 + ///\e
7.102 +
7.103 + ///\bug Unimplemented
7.104 + ///
7.105 + virtual void _setMin();
7.106 +
7.107 + };
7.108 +} //END OF NAMESPACE LEMON
7.109 +
7.110 +#endif //LEMON_LP_CPLEX_H
7.111 +