[Lemon-commits] [lemon_svn] alpar: r1691 - hugo/trunk/src/work/athos/lp
Lemon SVN
svn at lemon.cs.elte.hu
Mon Nov 6 20:47:02 CET 2006
Author: alpar
Date: Fri Mar 25 19:56:07 2005
New Revision: 1691
Modified:
hugo/trunk/src/work/athos/lp/lin_expr.h
hugo/trunk/src/work/athos/lp/lp_base.cc
hugo/trunk/src/work/athos/lp/lp_base.h
hugo/trunk/src/work/athos/lp/lp_test.cc
Log:
Constraints (expressions containing <= or >=) can be passed to addRow()
and setRow()
Modified: hugo/trunk/src/work/athos/lp/lin_expr.h
==============================================================================
--- hugo/trunk/src/work/athos/lp/lin_expr.h (original)
+++ hugo/trunk/src/work/athos/lp/lin_expr.h Fri Mar 25 19:56:07 2005
@@ -18,10 +18,8 @@
#define LEMON_LIN_EXPR_H
#include<vector>
-
-
#include<map>
-
+#include<lemon/utility.h>
///\file
///\brief Classes to handle linear expressions
namespace lemon {
@@ -39,6 +37,7 @@
Coeff const_comp;
public:
+ typedef True IsLinExpression;
///\e
SparseLinExpr() : Base(), const_comp(0) { }
///\e
@@ -262,6 +261,50 @@
///\relates SparseLinExpr
///
template <class V>
+ SparseLinExpr<V> operator+(const V &v,const typename V::ExprValue &c) {
+ SparseLinExpr<V> tmp(v);
+ tmp.constComp()=c;
+ return tmp;
+ }
+
+ ///\e
+
+ ///\relates SparseLinExpr
+ ///
+ template <class V>
+ SparseLinExpr<V> operator-(const V &v,const typename V::ExprValue &c) {
+ SparseLinExpr<V> tmp(v);
+ tmp.constComp()=-c;
+ return tmp;
+ }
+
+ ///\e
+
+ ///\relates SparseLinExpr
+ ///
+ template <class V>
+ SparseLinExpr<V> operator+(const typename V::ExprValue &c,const V &v) {
+ SparseLinExpr<V> tmp(v);
+ tmp.constComp()=c;
+ return tmp;
+ }
+
+ ///\e
+
+ ///\relates SparseLinExpr
+ ///
+ template <class V>
+ SparseLinExpr<V> operator-(const typename V::ExprValue &c,const V &v) {
+ SparseLinExpr<V> tmp(c);
+ tmp[v]=-1;
+ return tmp;
+ }
+
+ ///\e
+
+ ///\relates SparseLinExpr
+ ///
+ template <class V>
SparseLinExpr<V> operator+(const V &v1,const V &v2) {
SparseLinExpr<V> tmp(v1);
tmp[v2]+=1;
@@ -302,6 +345,154 @@
}
+ //////////////////////////////////////////////////////////////////////
+ /// Constraints
+ //////////////////////////////////////////////////////////////////////
+
+ template <class E>
+ class LinConstr
+ {
+ public:
+ typedef E Expr;
+ typedef typename E::Var Var;
+ typedef typename E::Coeff Coeff;
+
+ static const Coeff INF;
+ static const Coeff NaN;
+// static const Coeff INF=0;
+// static const Coeff NaN=1;
+
+ Expr expr;
+ Coeff lb,ub;
+
+ LinConstr() : expr(), lb(NaN), ub(NaN) {}
+ LinConstr(Coeff _lb,const Expr &e,Coeff _ub) :
+ expr(e), lb(_lb), ub(_ub) {}
+ LinConstr(const Expr &e,Coeff _ub) :
+ expr(e), lb(NaN), ub(_ub) {}
+ LinConstr(Coeff _lb,const Expr &e) :
+ expr(e), lb(_lb), ub(NaN) {}
+ };
+
+ template<class E>
+ const typename LinConstr<E>::Coeff LinConstr<E>::INF=
+ std::numeric_limits<Coeff>::infinity();
+ template<class E>
+ const typename LinConstr<E>::Coeff LinConstr<E>::NaN=
+ std::numeric_limits<Coeff>::quiet_NaN();
+
+
+ template<class E>
+ typename enable_if<typename E::IsLinExpression, LinConstr<E> >::type
+ operator<=(const E &e,const E &f)
+ {
+ return LinConstr<E>(-LinConstr<E>::INF,e-f,0);
+ }
+
+ template<class E>
+ typename enable_if<typename E::IsLinExpression, LinConstr<E> >::type
+ operator>=(const E &e,const E &f)
+ {
+ return LinConstr<E>(-LinConstr<E>::INF,f-e,0);
+ }
+
+ template<class E>
+ typename enable_if<typename E::IsLinExpression, LinConstr<E> >::type
+ operator==(const E &e,const E &f)
+ {
+ return LinConstr<E>(0,e-f,0);
+ }
+
+ //////////////////////////////
+
+ template<class E>
+ typename enable_if<typename E::IsLinExpression, LinConstr<E> >::type
+ operator<=(const E &e,const typename E::Coeff &n)
+ {
+ return LinConstr<E>(e,n);
+ }
+
+ template<class E>
+ typename enable_if<typename E::IsLinExpression, LinConstr<E> >::type
+ operator>=(const E &e,const typename E::Coeff &n)
+ {
+ return LinConstr<E>(n,e);
+ }
+
+ template<class E>
+ typename enable_if<typename E::IsLinExpression, LinConstr<E> >::type
+ operator==(const E &e,const typename E::Coeff &n)
+ {
+ return LinConstr<E>(n,e,n);
+ }
+
+ //////////////////////////////
+
+ template<class E>
+ typename enable_if<typename E::IsLinExpression, LinConstr<E> >::type
+ operator<=(const typename E::Coeff &n,const E &e)
+ {
+ return LinConstr<E>(n,e);
+ }
+
+ template<class E>
+ typename enable_if<typename E::IsLinExpression, LinConstr<E> >::type
+ operator>=(const typename E::Coeff &n,const E &e)
+ {
+ return LinConstr<E>(e,n);
+ }
+
+ template<class E>
+ typename enable_if<typename E::IsLinExpression, LinConstr<E> >::type
+ operator==(const typename E::Coeff &n,const E &e)
+ {
+ return LinConstr<E>(n,e,n);
+ }
+
+ //////////////////////////////
+
+ template<class E>
+ typename enable_if<typename E::IsLinExpression, LinConstr<E> >::type
+ operator<=(const typename E::Coeff &n,const LinConstr<E> &c)
+ {
+ LinConstr<E> tmp(c);
+ if(tmp.lb!=tmp.NaN) throw LogicError();
+ else tmp.lb=n;
+ return tmp;
+ }
+
+ template<class E>
+ typename enable_if<typename E::IsLinExpression, LinConstr<E> >::type
+ operator>=(const typename E::Coeff &n,const LinConstr<E> &c)
+ {
+ LinConstr<E> tmp(c);
+ if(tmp.ub!=tmp.NaN) throw LogicError();
+ else tmp.ub=n;
+ return tmp;
+ }
+
+ template<class E>
+ typename enable_if<typename E::IsLinExpression, LinConstr<E> >::type
+ operator<=(const LinConstr<E> &c,const typename E::Coeff &n)
+ {
+ LinConstr<E> tmp(c);
+ if(tmp.ub!=tmp.NaN) throw LogicError();
+ else tmp.ub=n;
+ return tmp;
+ }
+
+ template<class E>
+ typename enable_if<typename E::IsLinExpression, LinConstr<E> >::type
+ operator>=(const LinConstr<E> &c,const typename E::Coeff &n)
+ {
+ LinConstr<E> tmp(c);
+ if(tmp.lb!=tmp.NaN) throw LogicError();
+ else tmp.lb=n;
+ return tmp;
+ }
+
+
+
} //namespace lemon
#endif //LEMON_LIN_EXPR_H
Modified: hugo/trunk/src/work/athos/lp/lp_base.cc
==============================================================================
--- hugo/trunk/src/work/athos/lp/lp_base.cc (original)
+++ hugo/trunk/src/work/athos/lp/lp_base.cc Fri Mar 25 19:56:07 2005
@@ -22,6 +22,8 @@
const LpSolverBase::Value
LpSolverBase::INF = std::numeric_limits<Value>::infinity();
+ const LpSolverBase::Value
+ LpSolverBase::NaN = std::numeric_limits<Value>::quiet_NaN();
} //namespace lemon
Modified: hugo/trunk/src/work/athos/lp/lp_base.h
==============================================================================
--- hugo/trunk/src/work/athos/lp/lp_base.h (original)
+++ hugo/trunk/src/work/athos/lp/lp_base.h Fri Mar 25 19:56:07 2005
@@ -116,6 +116,8 @@
typedef double Value;
///The infinity constant
static const Value INF;
+ ///The not a number constant
+ static const Value NaN;
///Refer to a column of the LP.
@@ -167,6 +169,8 @@
///Linear expression
typedef SparseLinExpr<Col> Expr;
+ ///Linear constraint
+ typedef LinConstr<Expr> Constr;
protected:
_FixId rows;
@@ -318,6 +322,18 @@
_setRowUpperBound(rows.floatingId(r.id),u-e.constComp());
}
+ ///Set a row (i.e a constaint) of the LP
+
+ ///\param r is the row to be modified
+ ///\param c is a linear expression (see \ref Constr)
+ ///\bug This is a temportary function. The interface will change to
+ ///a better one.
+ void setRow(Row r, const Constr &c) {
+ Value lb= c.lb==NaN?-INF:lb;
+ Value ub= c.ub==NaN?INF:lb;
+ setRow(r,lb,c.expr,ub);
+ }
+
///Add a new row (i.e a new constaint) to the LP
///\param l is the lower bound (-\ref INF means no bound)
@@ -332,6 +348,18 @@
return r;
}
+ ///Add a new row (i.e a new constaint) to the LP
+
+ ///\param c is a linear expression (see \ref Constr)
+ ///\return The created row.
+ ///\bug This is a temportary function. The interface will change to
+ ///a better one.
+ Row addRow(const Constr &c) {
+ Row r=addRow();
+ setRow(r,c);
+ return r;
+ }
+
/// Set the lower bound of a column (i.e a variable)
/// The upper bound of a variable (column) have to be given by an
Modified: hugo/trunk/src/work/athos/lp/lp_test.cc
==============================================================================
--- hugo/trunk/src/work/athos/lp/lp_test.cc (original)
+++ hugo/trunk/src/work/athos/lp/lp_test.cc Fri Mar 25 19:56:07 2005
@@ -1,5 +1,6 @@
#include"lp_solver_skeleton.h"
#include"lp_glpk.h"
+#include<lemon/list_graph.h>
using namespace lemon;
@@ -36,9 +37,52 @@
lp.addRow(LP::INF,3.0*(x[1]+x[2]/2)-x[3],23);
lp.addRow(LP::INF,3.0*(p1+p2*2-5*p3+12-p4/3)+2*p4-4,23);
lp.addRow(LP::INF,3.0*(x[1]+x[2]*2-5*x[3]+12-x[4]/3)+2*x[4]-4,23);
+
+ lp.addRow(x[1]+x[3]<=x[5]-3);
+ lp.addRow(-7<=x[1]+x[3]-12<=3);
}
+template<class G,class C>
+double maxFlow(const G &g,const C &cap,typename G::Node s,typename G::Node t)
+{
+ LpGlpk lp;
+
+ typedef G Graph;
+ typedef typename G::Node Node;
+ typedef typename G::NodeIt NodeIt;
+ typedef typename G::Edge Edge;
+ typedef typename G::EdgeIt EdgeIt;
+ typedef typename G::OutEdgeIt OutEdgeIt;
+ typedef typename G::InEdgeIt InEdgeIt;
+
+ typename G::EdgeMap<LpGlpk::Col> x(g);
+ // lp.addColSet(x);
+ for(EdgeIt e(g);e!=INVALID;++e) x[e]=lp.addCol();
+
+ for(EdgeIt e(g);e!=INVALID;++e) {
+ lp.setColUpperBound(x[e],cap[e]);
+ lp.setColLowerBound(x[e],0);
+ }
+
+ for(NodeIt n(g);n!=INVALID;++n) if(n!=s&&n!=t) {
+ LpGlpk::Expr ex;
+ for(InEdgeIt e(g,n);e!=INVALID;++e) ex+=x[e];
+ for(OutEdgeIt e(g,n);e!=INVALID;++e) ex-=x[e];
+ lp.addRow(0,ex,0);
+ }
+ {
+ LpGlpk::Expr ex;
+ for(InEdgeIt e(g,t);e!=INVALID;++e) ex+=x[e];
+ for(OutEdgeIt e(g,t);e!=INVALID;++e) ex-=x[e];
+ lp.setObj(ex);
+ }
+
+ lp.solve();
+
+ return 0;
+}
+
int main()
{
LpSolverSkeleton lp_skel;
@@ -46,4 +90,10 @@
lpTest(lp_skel);
lpTest(lp_glpk);
+
+ ListGraph g;
+ ListGraph::EdgeMap<double> cap(g);
+
+ maxFlow(g,cap,ListGraph::NodeIt(g),ListGraph::NodeIt(g));
+
}
More information about the Lemon-commits
mailing list