Copied only so far.
authorathos
Tue, 22 Mar 2005 11:45:47 +0000
changeset 124088a2ab6bfc4a
parent 1239 8e1c3c30578b
child 1241 dadc9987c537
Copied only so far.
src/work/athos/lp/expression.h
src/work/athos/lp/expression_test.cc
src/work/athos/lp/lp_solver_base.h
src/work/athos/lp/lp_solver_wrapper.h
src/work/athos/lp/magic_square.cc
src/work/athos/lp/makefile
src/work/athos/lp/max_flow_by_lp.cc
src/work/athos/lp/max_flow_expression.cc
src/work/athos/lp/min_cost_gen_flow.h
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/src/work/athos/lp/expression.h	Tue Mar 22 11:45:47 2005 +0000
     1.3 @@ -0,0 +1,197 @@
     1.4 +// -*- c++ -*-
     1.5 +#ifndef LEMON_EXPRESSION_H
     1.6 +#define LEMON_EXPRESSION_H
     1.7 +
     1.8 +#include <iostream>
     1.9 +#include <map>
    1.10 +#include <limits>
    1.11 +
    1.12 +namespace lemon {
    1.13 +
    1.14 +  /*! \brief Linear expression
    1.15 +
    1.16 +    \c Expr<_Col,_Value> implements a class of linear expressions with the 
    1.17 +    operations of addition and multiplication with scalar. 
    1.18 +
    1.19 +    \author Marton Makai
    1.20 +   */
    1.21 +  template <typename _Col, typename _Value>
    1.22 +  class Expr;
    1.23 +
    1.24 +  template <typename _Col, typename _Value>
    1.25 +  class Expr {
    1.26 +//  protected:
    1.27 +  public:
    1.28 +    typedef 
    1.29 +    typename std::map<_Col, _Value> Data; 
    1.30 +    Data data;
    1.31 +  public:
    1.32 +    void simplify() {
    1.33 +      for (typename Data::iterator i=data.begin(); 
    1.34 +	   i!=data.end(); ++i) {
    1.35 +	if ((*i).second==0) data.erase(i);
    1.36 +      }
    1.37 +    }
    1.38 +    Expr() { }
    1.39 +    Expr(_Col _col) { 
    1.40 +      data.insert(std::make_pair(_col, 1));
    1.41 +    }
    1.42 +    Expr& operator*=(_Value _value) {
    1.43 +      for (typename Data::iterator i=data.begin(); 
    1.44 +	   i!=data.end(); ++i) {
    1.45 +	(*i).second *= _value;
    1.46 +      }
    1.47 +      simplify();
    1.48 +      return *this;
    1.49 +    }
    1.50 +    Expr& operator+=(const Expr<_Col, _Value>& expr) {
    1.51 +      for (typename Data::const_iterator j=expr.data.begin(); 
    1.52 +	   j!=expr.data.end(); ++j) {
    1.53 +	typename Data::iterator i=data.find((*j).first);
    1.54 +	if (i==data.end()) {
    1.55 +	  data.insert(std::make_pair((*j).first, (*j).second));
    1.56 +	} else {
    1.57 +	  (*i).second+=(*j).second;
    1.58 +	}
    1.59 +      }
    1.60 +      simplify();
    1.61 +      return *this;
    1.62 +    }
    1.63 +    Expr& operator-=(const Expr<_Col, _Value>& expr) {
    1.64 +      for (typename Data::const_iterator j=expr.data.begin(); 
    1.65 +	   j!=expr.data.end(); ++j) {
    1.66 +	typename Data::iterator i=data.find((*j).first);
    1.67 +	if (i==data.end()) {
    1.68 +	  data.insert(std::make_pair((*j).first, -(*j).second));
    1.69 +	} else {
    1.70 +	  (*i).second+=-(*j).second;
    1.71 +	}
    1.72 +      }
    1.73 +      simplify();
    1.74 +      return *this;
    1.75 +    }
    1.76 +    template <typename _C, typename _V> 
    1.77 +    friend std::ostream& operator<<(std::ostream& os, 
    1.78 +				    const Expr<_C, _V>& expr);
    1.79 +  };
    1.80 +
    1.81 +  template <typename _Col, typename _Value>
    1.82 +  Expr<_Col, _Value> operator*(_Value _value, _Col _col) {
    1.83 +    Expr<_Col, _Value> tmp(_col);
    1.84 +    tmp*=_value;
    1.85 +    tmp.simplify();
    1.86 +    return tmp;
    1.87 +  }
    1.88 +
    1.89 +  template <typename _Col, typename _Value>
    1.90 +  Expr<_Col, _Value> operator*(_Value _value, 
    1.91 +			       const Expr<_Col, _Value>& expr) {
    1.92 +    Expr<_Col, _Value> tmp(expr);
    1.93 +    tmp*=_value;
    1.94 +    tmp.simplify();
    1.95 +    return tmp;
    1.96 +  }
    1.97 +
    1.98 +  template <typename _Col, typename _Value>
    1.99 +  Expr<_Col, _Value> operator+(const Expr<_Col, _Value>& expr1, 
   1.100 +			       const Expr<_Col, _Value>& expr2) {
   1.101 +    Expr<_Col, _Value> tmp(expr1);
   1.102 +    tmp+=expr2;
   1.103 +    tmp.simplify();
   1.104 +    return tmp;
   1.105 +  }
   1.106 +
   1.107 +  template <typename _Col, typename _Value>
   1.108 +  Expr<_Col, _Value> operator-(const Expr<_Col, _Value>& expr1, 
   1.109 +			       const Expr<_Col, _Value>& expr2) {
   1.110 +    Expr<_Col, _Value> tmp(expr1);
   1.111 +    tmp-=expr2;
   1.112 +    tmp.simplify();
   1.113 +    return tmp;
   1.114 +  }
   1.115 +
   1.116 +  template <typename _Col, typename _Value>
   1.117 +  std::ostream& operator<<(std::ostream& os, 
   1.118 +			   const Expr<_Col, _Value>& expr) {
   1.119 +    for (typename Expr<_Col, _Value>::Data::const_iterator i=
   1.120 +	   expr.data.begin(); 
   1.121 +	 i!=expr.data.end(); ++i) {
   1.122 +      os << (*i).second << "*" << (*i).first << " ";
   1.123 +    }
   1.124 +    return os;
   1.125 +  }
   1.126 +
   1.127 +  template <typename _Col, typename _Value>
   1.128 +  class LConstr {
   1.129 +    //  protected:
   1.130 +  public:
   1.131 +    Expr<_Col, _Value> expr;
   1.132 +    _Value lo;
   1.133 +  public:
   1.134 +    LConstr(const Expr<_Col, _Value>& _expr, _Value _lo) : 
   1.135 +      expr(_expr), lo(_lo) { }
   1.136 +  };
   1.137 +  
   1.138 +  template <typename _Col, typename _Value>
   1.139 +  LConstr<_Col, _Value> 
   1.140 +  operator<=(_Value lo, const Expr<_Col, _Value>& expr) {
   1.141 +    return LConstr<_Col, _Value>(expr, lo);
   1.142 +  }
   1.143 +
   1.144 +  template <typename _Col, typename _Value>
   1.145 +  class UConstr {
   1.146 +    //  protected:
   1.147 +  public:
   1.148 +    Expr<_Col, _Value> expr;
   1.149 +    _Value up;
   1.150 +  public:
   1.151 +    UConstr(const Expr<_Col, _Value>& _expr, _Value _up) : 
   1.152 +      expr(_expr), up(_up) { }
   1.153 +  };
   1.154 +
   1.155 +  template <typename _Col, typename _Value>
   1.156 +  UConstr<_Col, _Value> 
   1.157 +  operator<=(const Expr<_Col, _Value>& expr, _Value up) {
   1.158 +    return UConstr<_Col, _Value>(expr, up);
   1.159 +  }
   1.160 +
   1.161 +  template <typename _Col, typename _Value>
   1.162 +  class Constr {
   1.163 +    //  protected:
   1.164 +  public:
   1.165 +    Expr<_Col, _Value> expr;
   1.166 +    _Value lo, up;
   1.167 +  public:
   1.168 +    Constr(const Expr<_Col, _Value>& _expr, _Value _lo, _Value _up) : 
   1.169 +      expr(_expr), lo(_lo), up(_up) { }
   1.170 +    Constr(const LConstr<_Col, _Value>& _lconstr) : 
   1.171 +      expr(_lconstr.expr), 
   1.172 +      lo(_lconstr.lo), 
   1.173 +      up(std::numeric_limits<_Value>::infinity()) { }
   1.174 +    Constr(const UConstr<_Col, _Value>& _uconstr) : 
   1.175 +      expr(_uconstr.expr), 
   1.176 +      lo(-std::numeric_limits<_Value>::infinity()), 
   1.177 +      up(_uconstr.up) { }
   1.178 +  };
   1.179 +
   1.180 +  template <typename _Col, typename _Value>
   1.181 +  Constr<_Col, _Value> 
   1.182 +  operator<=(const LConstr<_Col, _Value>& lconstr, _Value up) {
   1.183 +    return Constr<_Col, _Value>(lconstr.expr, lconstr.lo, up);
   1.184 +  }
   1.185 +
   1.186 +  template <typename _Col, typename _Value>
   1.187 +  Constr<_Col, _Value> 
   1.188 +  operator<=(_Value lo, const UConstr<_Col, _Value>& uconstr) {
   1.189 +    return Constr<_Col, _Value>(uconstr.expr, lo, uconstr.up);
   1.190 +  }
   1.191 +
   1.192 +  template <typename _Col, typename _Value>
   1.193 +  Constr<_Col, _Value> 
   1.194 +  operator==(const Expr<_Col, _Value>& expr, _Value value) {
   1.195 +    return Constr<_Col, _Value>(expr, value, value);
   1.196 +  }
   1.197 +  
   1.198 +} //namespace lemon
   1.199 +
   1.200 +#endif //LEMON_EXPRESSION_H
     2.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     2.2 +++ b/src/work/athos/lp/expression_test.cc	Tue Mar 22 11:45:47 2005 +0000
     2.3 @@ -0,0 +1,23 @@
     2.4 +#include <expression.h>
     2.5 +#include <iostream>
     2.6 +#include <string>
     2.7 +
     2.8 +using std::cout;
     2.9 +using std::endl;
    2.10 +using std::string;
    2.11 +using namespace lemon;
    2.12 +
    2.13 +int main() {
    2.14 +  Expr<string, double> b;
    2.15 +  cout << b << endl;
    2.16 +  Expr<string, double> c("f");
    2.17 +  cout << c << endl;
    2.18 +  Expr<string, double> d=8.0*string("g");
    2.19 +  cout << d << endl;
    2.20 +  c*=5;
    2.21 +  cout << c << endl;
    2.22 +  Expr<string, double> e=c;
    2.23 +  e+=8.9*9.0*string("l");
    2.24 +  cout << e << endl;
    2.25 +  cout << c+d << endl;
    2.26 +}
     3.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     3.2 +++ b/src/work/athos/lp/lp_solver_base.h	Tue Mar 22 11:45:47 2005 +0000
     3.3 @@ -0,0 +1,1116 @@
     3.4 +// -*- c++ -*-
     3.5 +#ifndef LEMON_LP_SOLVER_BASE_H
     3.6 +#define LEMON_LP_SOLVER_BASE_H
     3.7 +
     3.8 +///\ingroup misc
     3.9 +///\file
    3.10 +
    3.11 +// #include <stdio.h>
    3.12 +#include <stdlib.h>
    3.13 +#include <iostream>
    3.14 +#include <map>
    3.15 +#include <limits>
    3.16 +// #include <stdio>
    3.17 +//#include <stdlib>
    3.18 +extern "C" {
    3.19 +#include "glpk.h"
    3.20 +}
    3.21 +
    3.22 +#include <iostream>
    3.23 +#include <vector>
    3.24 +#include <string>
    3.25 +#include <list>
    3.26 +#include <memory>
    3.27 +#include <utility>
    3.28 +
    3.29 +#include <lemon/invalid.h>
    3.30 +#include <expression.h>
    3.31 +//#include <stp.h>
    3.32 +//#include <lemon/max_flow.h>
    3.33 +//#include <augmenting_flow.h>
    3.34 +//#include <iter_map.h>
    3.35 +
    3.36 +using std::cout;
    3.37 +using std::cin;
    3.38 +using std::endl;
    3.39 +
    3.40 +namespace lemon {
    3.41 +  
    3.42 +  /// \addtogroup misc
    3.43 +  /// @{
    3.44 +
    3.45 +  /// \brief A partitioned vector with iterable classes.
    3.46 +  ///
    3.47 +  /// This class implements a container in which the data is stored in an 
    3.48 +  /// stl vector, the range is partitioned into sets and each set is 
    3.49 +  /// doubly linked in a list. 
    3.50 +  /// That is, each class is iterable by lemon iterators, and any member of 
    3.51 +  /// the vector can bo moved to an other class.
    3.52 +  template <typename T>
    3.53 +  class IterablePartition {
    3.54 +  protected:
    3.55 +    struct Node {
    3.56 +      T data;
    3.57 +      int prev; //invalid az -1
    3.58 +      int next; 
    3.59 +    };
    3.60 +    std::vector<Node> nodes;
    3.61 +    struct Tip {
    3.62 +      int first;
    3.63 +      int last;
    3.64 +    };
    3.65 +    std::vector<Tip> tips;
    3.66 +  public:
    3.67 +    /// The classes are indexed by integers from \c 0 to \c classNum()-1.
    3.68 +    int classNum() const { return tips.size(); }
    3.69 +    /// This lemon style iterator iterates through a class. 
    3.70 +    class Class;
    3.71 +    /// Constructor. The number of classes is to be given which is fixed 
    3.72 +    /// over the life of the container. 
    3.73 +    /// The partition classes are indexed from 0 to class_num-1. 
    3.74 +    IterablePartition(int class_num) { 
    3.75 +      for (int i=0; i<class_num; ++i) {
    3.76 +	Tip t;
    3.77 +	t.first=t.last=-1;
    3.78 +	tips.push_back(t);
    3.79 +      }
    3.80 +    }
    3.81 +  protected:
    3.82 +    void befuz(Class it, int class_id) {
    3.83 +      if (tips[class_id].first==-1) {
    3.84 +	if (tips[class_id].last==-1) {
    3.85 +	  nodes[it.i].prev=nodes[it.i].next=-1;
    3.86 +	  tips[class_id].first=tips[class_id].last=it.i;
    3.87 +	}
    3.88 +      } else {
    3.89 +	nodes[it.i].prev=tips[class_id].last;
    3.90 +	nodes[it.i].next=-1;
    3.91 +	nodes[tips[class_id].last].next=it.i;
    3.92 +	tips[class_id].last=it.i;
    3.93 +      }
    3.94 +    }
    3.95 +    void kifuz(Class it, int class_id) {
    3.96 +      if (tips[class_id].first==it.i) {
    3.97 +	if (tips[class_id].last==it.i) {
    3.98 +	  tips[class_id].first=tips[class_id].last=-1;
    3.99 +	} else {
   3.100 +	  tips[class_id].first=nodes[it.i].next;
   3.101 +	  nodes[nodes[it.i].next].prev=-1;
   3.102 +	}
   3.103 +      } else {
   3.104 +	if (tips[class_id].last==it.i) {
   3.105 +	  tips[class_id].last=nodes[it.i].prev;
   3.106 +	  nodes[nodes[it.i].prev].next=-1;
   3.107 +	} else {
   3.108 +	  nodes[nodes[it.i].next].prev=nodes[it.i].prev;
   3.109 +	  nodes[nodes[it.i].prev].next=nodes[it.i].next;
   3.110 +	}
   3.111 +      }
   3.112 +    }
   3.113 +  public:
   3.114 +    /// A new element with data \c t is pushed into the vector and into class 
   3.115 +    /// \c class_id.
   3.116 +    Class push_back(const T& t, int class_id) { 
   3.117 +      Node n;
   3.118 +      n.data=t;
   3.119 +      nodes.push_back(n);
   3.120 +      int i=nodes.size()-1;
   3.121 +      befuz(i, class_id);
   3.122 +      return i;
   3.123 +    }
   3.124 +    /// A member is moved to an other class.
   3.125 +    void set(Class it, int old_class_id, int new_class_id) {
   3.126 +      kifuz(it.i, old_class_id);
   3.127 +      befuz(it.i, new_class_id);
   3.128 +    }
   3.129 +    /// Returns the data pointed by \c it.
   3.130 +    T& operator[](Class it) { return nodes[it.i].data; }
   3.131 +    /// Returns the data pointed by \c it.
   3.132 +    const T& operator[](Class it) const { return nodes[it.i].data; }
   3.133 +    ///.
   3.134 +    class Class {
   3.135 +      friend class IterablePartition;
   3.136 +    protected:
   3.137 +      int i;
   3.138 +    public:
   3.139 +      /// Default constructor.
   3.140 +      Class() { }
   3.141 +      /// This constructor constructs an iterator which points
   3.142 +      /// to the member of th container indexed by the integer _i.
   3.143 +      Class(const int& _i) : i(_i) { }
   3.144 +      /// Invalid constructor.
   3.145 +      Class(const Invalid&) : i(-1) { }
   3.146 +      friend bool operator<(const Class& x, const Class& y);
   3.147 +      friend std::ostream& operator<<(std::ostream& os, 
   3.148 +				      const Class& it);
   3.149 +      bool operator==(const Class& node) const {return i == node.i;}
   3.150 +      bool operator!=(const Class& node) const {return i != node.i;}
   3.151 +    };
   3.152 +    friend bool operator<(const Class& x, const Class& y) {
   3.153 +      return (x.i < y.i);
   3.154 +    }
   3.155 +    friend std::ostream& operator<<(std::ostream& os, 
   3.156 +				    const Class& it) {
   3.157 +      os << it.i;
   3.158 +      return os;
   3.159 +    }
   3.160 +    /// First member of class \c class_id.
   3.161 +    Class& first(Class& it, int class_id) const {
   3.162 +      it.i=tips[class_id].first;
   3.163 +      return it;
   3.164 +    }
   3.165 +    /// Next member.
   3.166 +    Class& next(Class& it) const {
   3.167 +      it.i=nodes[it.i].next;
   3.168 +      return it;
   3.169 +    }
   3.170 +    /// True iff the iterator is valid.
   3.171 +    bool valid(const Class& it) const { return it.i!=-1; }
   3.172 +
   3.173 +    class ClassIt : public Class {
   3.174 +      const IterablePartition* iterable_partition;
   3.175 +    public:
   3.176 +      ClassIt() { }
   3.177 +      ClassIt(Invalid i) : Class(i) { }
   3.178 +      ClassIt(const IterablePartition& _iterable_partition, 
   3.179 +	      const int& i) : iterable_partition(&_iterable_partition) {
   3.180 +        _iterable_partition.first(*this, i);
   3.181 +      }
   3.182 +      ClassIt(const IterablePartition& _iterable_partition, 
   3.183 +	      const Class& _class) : 
   3.184 +	Class(_class), iterable_partition(&_iterable_partition) { }
   3.185 +      ClassIt& operator++() {
   3.186 +        iterable_partition->next(*this);
   3.187 +        return *this;
   3.188 +      }
   3.189 +    };
   3.190 +
   3.191 +  };
   3.192 +
   3.193 +
   3.194 +  /*! \e
   3.195 +    \todo kellenene uj iterable structure bele, mert ez nem az igazi
   3.196 +    \todo A[x,y]-t cserel. Jobboldal, baloldal csere.
   3.197 +    \todo LEKERDEZESEK!!!
   3.198 +    \todo DOKSI!!!! Doxygen group!!!
   3.199 +    The aim of this class is to give a general surface to different 
   3.200 +    solvers, i.e. it makes possible to write algorithms using LP's, 
   3.201 +    in which the solver can be changed to an other one easily.
   3.202 +    \nosubgrouping
   3.203 +  */
   3.204 +  template <typename _Value>
   3.205 +  class LPSolverBase {
   3.206 +    
   3.207 +    /*! @name Uncategorized functions and types (public members)
   3.208 +    */
   3.209 +    //@{
   3.210 +  public:
   3.211 +
   3.212 +    //UNCATEGORIZED
   3.213 +
   3.214 +    /// \e
   3.215 +    typedef IterablePartition<int> Rows;
   3.216 +    /// \e
   3.217 +    typedef IterablePartition<int> Cols;
   3.218 +    /// \e
   3.219 +    typedef _Value Value;
   3.220 +    /// \e
   3.221 +    typedef Rows::Class Row;
   3.222 +    /// \e
   3.223 +    typedef Cols::Class Col;
   3.224 +  public:
   3.225 +    /// \e
   3.226 +    IterablePartition<int> row_iter_map;
   3.227 +    /// \e
   3.228 +    IterablePartition<int> col_iter_map;
   3.229 +    /// \e
   3.230 +    std::vector<Row> int_row_map;
   3.231 +    /// \e
   3.232 +    std::vector<Col> int_col_map;
   3.233 +    /// \e
   3.234 +    const int VALID_CLASS;
   3.235 +    /// \e
   3.236 +    const int INVALID_CLASS;
   3.237 +    /// \e 
   3.238 +    static const _Value INF;
   3.239 +  public:
   3.240 +    /// \e
   3.241 +    LPSolverBase() : row_iter_map(2), 
   3.242 +		     col_iter_map(2), 
   3.243 +		     VALID_CLASS(0), INVALID_CLASS(1) { }
   3.244 +    /// \e
   3.245 +    virtual ~LPSolverBase() { }
   3.246 +    //@}
   3.247 +
   3.248 +    /*! @name Medium level interface (public members)
   3.249 +      These functions appear in the low level and also in the high level 
   3.250 +      interfaces thus these each of these functions have to be implemented 
   3.251 +      only once in the different interfaces.
   3.252 +      This means that these functions have to be reimplemented for all of the 
   3.253 +      different lp solvers. These are basic functions, and have the same 
   3.254 +      parameter lists in the low and high level interfaces. 
   3.255 +    */
   3.256 +    //@{
   3.257 +  public:
   3.258 +
   3.259 +    //UNCATEGORIZED FUNCTIONS
   3.260 +
   3.261 +    /// \e
   3.262 +    virtual void setMinimize() = 0;
   3.263 +    /// \e
   3.264 +    virtual void setMaximize() = 0;
   3.265 +
   3.266 +    //SOLVER FUNCTIONS
   3.267 +
   3.268 +    /// \e
   3.269 +    virtual void solveSimplex() = 0;
   3.270 +    /// \e
   3.271 +    virtual void solvePrimalSimplex() = 0;
   3.272 +    /// \e
   3.273 +    virtual void solveDualSimplex() = 0;
   3.274 +
   3.275 +    //SOLUTION RETRIEVING
   3.276 +
   3.277 +    /// \e
   3.278 +    virtual _Value getObjVal() = 0;
   3.279 +
   3.280 +    //OTHER FUNCTIONS
   3.281 +
   3.282 +    /// \e
   3.283 +    virtual int rowNum() const = 0;
   3.284 +    /// \e
   3.285 +    virtual int colNum() const = 0;
   3.286 +    /// \e
   3.287 +    virtual int warmUp() = 0;
   3.288 +    /// \e
   3.289 +    virtual void printWarmUpStatus(int i) = 0;
   3.290 +    /// \e
   3.291 +    virtual int getPrimalStatus() = 0;
   3.292 +    /// \e
   3.293 +    virtual void printPrimalStatus(int i) = 0;
   3.294 +    /// \e
   3.295 +    virtual int getDualStatus() = 0;
   3.296 +    /// \e
   3.297 +    virtual void printDualStatus(int i) = 0;
   3.298 +    /// Returns the status of the slack variable assigned to row \c row.
   3.299 +    virtual int getRowStat(const Row& row) = 0;
   3.300 +    /// \e
   3.301 +    virtual void printRowStatus(int i) = 0;
   3.302 +    /// Returns the status of the variable assigned to column \c col.
   3.303 +    virtual int getColStat(const Col& col) = 0;
   3.304 +    /// \e
   3.305 +    virtual void printColStatus(int i) = 0;
   3.306 +
   3.307 +    //@}
   3.308 +
   3.309 +    /*! @name Low level interface (protected members)
   3.310 +      Problem manipulating functions in the low level interface
   3.311 +    */
   3.312 +    //@{
   3.313 +  protected:
   3.314 +
   3.315 +    //MATRIX MANIPULATING FUNCTIONS
   3.316 +
   3.317 +    /// \e
   3.318 +    virtual int _addCol() = 0;
   3.319 +    /// \e
   3.320 +    virtual int _addRow() = 0;
   3.321 +    /// \e
   3.322 +    virtual void _eraseCol(int i) = 0;
   3.323 +    /// \e
   3.324 +    virtual void _eraseRow(int i) = 0;
   3.325 +    /// \e
   3.326 +    virtual void _setRowCoeffs(int i, 
   3.327 +			       const std::vector<std::pair<int, _Value> >& coeffs) = 0;
   3.328 +    /// \e
   3.329 +    /// This routine modifies \c coeffs only by the \c push_back method.
   3.330 +    virtual void _getRowCoeffs(int i, 
   3.331 +			       std::vector<std::pair<int, _Value> >& coeffs) = 0;
   3.332 +    /// \e
   3.333 +    virtual void _setColCoeffs(int i, 
   3.334 +			       const std::vector<std::pair<int, _Value> >& coeffs) = 0;
   3.335 +    /// \e
   3.336 +    /// This routine modifies \c coeffs only by the \c push_back method.
   3.337 +    virtual void _getColCoeffs(int i, 
   3.338 +			       std::vector<std::pair<int, _Value> >& coeffs) = 0;
   3.339 +    /// \e
   3.340 +    virtual void _setCoeff(int col, int row, _Value value) = 0;
   3.341 +    /// \e
   3.342 +    virtual _Value _getCoeff(int col, int row) = 0;
   3.343 +    //  public:
   3.344 +    //    /// \e
   3.345 +    //    enum Bound { FREE, LOWER, UPPER, DOUBLE, FIXED };
   3.346 +  protected:
   3.347 +    /// \e
   3.348 +    /// The lower bound of a variable (column) have to be given by an 
   3.349 +    /// extended number of type _Value, i.e. a finite number of type 
   3.350 +    /// _Value or -INF.
   3.351 +    virtual void _setColLowerBound(int i, _Value value) = 0;
   3.352 +    /// \e
   3.353 +    /// The lower bound of a variable (column) is an 
   3.354 +    /// extended number of type _Value, i.e. a finite number of type 
   3.355 +    /// _Value or -INF.
   3.356 +    virtual _Value _getColLowerBound(int i) = 0;
   3.357 +    /// \e
   3.358 +    /// The upper bound of a variable (column) have to be given by an 
   3.359 +    /// extended number of type _Value, i.e. a finite number of type 
   3.360 +    /// _Value or INF.
   3.361 +    virtual void _setColUpperBound(int i, _Value value) = 0;
   3.362 +    /// \e
   3.363 +    /// The upper bound of a variable (column) is an 
   3.364 +    /// extended number of type _Value, i.e. a finite number of type 
   3.365 +    /// _Value or INF.
   3.366 +    virtual _Value _getColUpperBound(int i) = 0;
   3.367 +    /// \e
   3.368 +    /// The lower bound of a linear expression (row) have to be given by an 
   3.369 +    /// extended number of type _Value, i.e. a finite number of type 
   3.370 +    /// _Value or -INF.
   3.371 +    virtual void _setRowLowerBound(int i, _Value value) = 0;
   3.372 +    /// \e
   3.373 +    /// The lower bound of a linear expression (row) is an 
   3.374 +    /// extended number of type _Value, i.e. a finite number of type 
   3.375 +    /// _Value or -INF.
   3.376 +    virtual _Value _getRowLowerBound(int i) = 0;
   3.377 +    /// \e
   3.378 +    /// The upper bound of a linear expression (row) have to be given by an 
   3.379 +    /// extended number of type _Value, i.e. a finite number of type 
   3.380 +    /// _Value or INF.
   3.381 +    virtual void _setRowUpperBound(int i, _Value value) = 0;
   3.382 +    /// \e
   3.383 +    /// The upper bound of a linear expression (row) is an 
   3.384 +    /// extended number of type _Value, i.e. a finite number of type 
   3.385 +    /// _Value or INF.
   3.386 +    virtual _Value _getRowUpperBound(int i) = 0;
   3.387 +    /// \e
   3.388 +    virtual void _setObjCoeff(int i, _Value obj_coef) = 0;
   3.389 +    /// \e
   3.390 +    virtual _Value _getObjCoeff(int i) = 0;
   3.391 +    
   3.392 +    //SOLUTION RETRIEVING
   3.393 +
   3.394 +    /// \e
   3.395 +    virtual _Value _getPrimal(int i) = 0;
   3.396 +    //@}
   3.397 +    
   3.398 +    /*! @name High level interface (public members)
   3.399 +      Problem manipulating functions in the high level interface
   3.400 +    */
   3.401 +    //@{
   3.402 +  public:
   3.403 +
   3.404 +    //MATRIX MANIPULATING FUNCTIONS
   3.405 +
   3.406 +    /// \e
   3.407 +    Col addCol() {
   3.408 +      int i=_addCol();  
   3.409 +      Col col;
   3.410 +      col_iter_map.first(col, INVALID_CLASS);
   3.411 +      if (col_iter_map.valid(col)) { //van hasznalhato hely
   3.412 +	col_iter_map.set(col, INVALID_CLASS, VALID_CLASS);
   3.413 +	col_iter_map[col]=i;
   3.414 +      } else { //a cucc vegere kell inzertalni mert nincs szabad hely
   3.415 +	col=col_iter_map.push_back(i, VALID_CLASS);
   3.416 +      }
   3.417 +      int_col_map.push_back(col);
   3.418 +      return col;
   3.419 +    }
   3.420 +    /// \e
   3.421 +    Row addRow() {
   3.422 +      int i=_addRow();
   3.423 +      Row row;
   3.424 +      row_iter_map.first(row, INVALID_CLASS);
   3.425 +      if (row_iter_map.valid(row)) { //van hasznalhato hely
   3.426 +	row_iter_map.set(row, INVALID_CLASS, VALID_CLASS);
   3.427 +	row_iter_map[row]=i;
   3.428 +      } else { //a cucc vegere kell inzertalni mert nincs szabad hely
   3.429 +	row=row_iter_map.push_back(i, VALID_CLASS);
   3.430 +      }
   3.431 +      int_row_map.push_back(row);
   3.432 +      return row;
   3.433 +    }
   3.434 +    /// \e
   3.435 +    void eraseCol(const Col& col) {
   3.436 +      col_iter_map.set(col, VALID_CLASS, INVALID_CLASS);
   3.437 +      int cols[2];
   3.438 +      cols[1]=col_iter_map[col];
   3.439 +      _eraseCol(cols[1]);
   3.440 +      col_iter_map[col]=0; //glpk specifikus, de kell ez??
   3.441 +      Col it;
   3.442 +      for (col_iter_map.first(it, VALID_CLASS); 
   3.443 +	   col_iter_map.valid(it); col_iter_map.next(it)) {
   3.444 +	if (col_iter_map[it]>cols[1]) --col_iter_map[it];
   3.445 +      }
   3.446 +      int_col_map.erase(int_col_map.begin()+cols[1]);
   3.447 +    }
   3.448 +    /// \e
   3.449 +    void eraseRow(const Row& row) {
   3.450 +      row_iter_map.set(row, VALID_CLASS, INVALID_CLASS);
   3.451 +      int rows[2];
   3.452 +      rows[1]=row_iter_map[row];
   3.453 +      _eraseRow(rows[1]);
   3.454 +      row_iter_map[row]=0; //glpk specifikus, de kell ez??
   3.455 +      Row it;
   3.456 +      for (row_iter_map.first(it, VALID_CLASS); 
   3.457 +	   row_iter_map.valid(it); row_iter_map.next(it)) {
   3.458 +	if (row_iter_map[it]>rows[1]) --row_iter_map[it];
   3.459 +      }
   3.460 +      int_row_map.erase(int_row_map.begin()+rows[1]);
   3.461 +    }
   3.462 +    /// \e
   3.463 +    void setCoeff(Col col, Row row, _Value value) {
   3.464 +      _setCoeff(col_iter_map[col], row_iter_map[row], value);
   3.465 +    }
   3.466 +    /// \e
   3.467 +    _Value getCoeff(Col col, Row row) {
   3.468 +      return _getCoeff(col_iter_map[col], row_iter_map[row], value);
   3.469 +    }
   3.470 +    /// \e
   3.471 +    void setColLowerBound(Col col, _Value lo) {
   3.472 +      _setColLowerBound(col_iter_map[col], lo);
   3.473 +    }
   3.474 +    /// \e
   3.475 +    _Value getColLowerBound(Col col) {
   3.476 +      return _getColLowerBound(col_iter_map[col]);
   3.477 +    }
   3.478 +    /// \e
   3.479 +    void setColUpperBound(Col col, _Value up) {
   3.480 +      _setColUpperBound(col_iter_map[col], up);
   3.481 +    }
   3.482 +    /// \e
   3.483 +    _Value getColUpperBound(Col col) {      
   3.484 +      return _getColUpperBound(col_iter_map[col]);
   3.485 +    }
   3.486 +    /// \e
   3.487 +    void setRowLowerBound(Row row, _Value lo) {
   3.488 +      _setRowLowerBound(row_iter_map[row], lo);
   3.489 +    }
   3.490 +    /// \e
   3.491 +    _Value getRowLowerBound(Row row) {
   3.492 +      return _getRowLowerBound(row_iter_map[row]);
   3.493 +    }
   3.494 +    /// \e
   3.495 +    void setRowUpperBound(Row row, _Value up) {
   3.496 +      _setRowUpperBound(row_iter_map[row], up);
   3.497 +    }
   3.498 +    /// \e
   3.499 +    _Value getRowUpperBound(Row row) {      
   3.500 +      return _getRowUpperBound(row_iter_map[row]);
   3.501 +    }
   3.502 +    /// \e
   3.503 +    void setObjCoeff(const Col& col, _Value obj_coef) {
   3.504 +      _setObjCoeff(col_iter_map[col], obj_coef);
   3.505 +    }
   3.506 +    /// \e
   3.507 +    _Value getObjCoeff(const Col& col) {
   3.508 +      return _getObjCoeff(col_iter_map[col]);
   3.509 +    }
   3.510 +
   3.511 +    //SOLUTION RETRIEVING FUNCTIONS
   3.512 +
   3.513 +    /// \e
   3.514 +    _Value getPrimal(const Col& col) {
   3.515 +      return _getPrimal(col_iter_map[col]);
   3.516 +    }    
   3.517 +
   3.518 +    //@}
   3.519 +
   3.520 +    /*! @name User friend interface
   3.521 +      Problem manipulating functions in the user friend interface
   3.522 +    */
   3.523 +    //@{
   3.524 +
   3.525 +    //EXPRESSION TYPES
   3.526 +
   3.527 +    /// \e
   3.528 +    typedef Expr<Col, _Value> Expression;
   3.529 +    /// \e
   3.530 +    typedef Expr<Row, _Value> DualExpression;
   3.531 +    /// \e
   3.532 +    typedef Constr<Col, _Value> Constraint;
   3.533 +
   3.534 +    //MATRIX MANIPULATING FUNCTIONS
   3.535 +
   3.536 +    /// \e
   3.537 +    void setRowCoeffs(Row row, const Expression& expr) {
   3.538 +      std::vector<std::pair<int, _Value> > row_coeffs;
   3.539 +      for(typename Expression::Data::const_iterator i=expr.data.begin(); 
   3.540 +	  i!=expr.data.end(); ++i) {
   3.541 +	row_coeffs.push_back(std::make_pair
   3.542 +			     (col_iter_map[(*i).first], (*i).second));
   3.543 +      }
   3.544 +      _setRowCoeffs(row_iter_map[row], row_coeffs);
   3.545 +    }
   3.546 +    /// \e 
   3.547 +    void setRow(Row row, const Constraint& constr) {
   3.548 +      setRowCoeffs(row, constr.expr);
   3.549 +      setRowLowerBound(row, constr.lo);
   3.550 +      setRowUpperBound(row, constr.up);
   3.551 +    }
   3.552 +    /// \e 
   3.553 +    Row addRow(const Constraint& constr) {
   3.554 +      Row row=addRow();
   3.555 +      setRowCoeffs(row, constr.expr);
   3.556 +      setRowLowerBound(row, constr.lo);
   3.557 +      setRowUpperBound(row, constr.up);
   3.558 +      return row;
   3.559 +    }
   3.560 +    /// \e
   3.561 +    /// This routine modifies \c expr by only adding to it.
   3.562 +    void getRowCoeffs(Row row, Expression& expr) {
   3.563 +      std::vector<std::pair<int, _Value> > row_coeffs;
   3.564 +      _getRowCoeffs(row_iter_map[row], row_coeffs);
   3.565 +      for(typename std::vector<std::pair<int, _Value> >::const_iterator 
   3.566 + 	    i=row_coeffs.begin(); i!=row_coeffs.end(); ++i) {
   3.567 + 	expr+= (*i).second*int_col_map[(*i).first];
   3.568 +      }
   3.569 +    }
   3.570 +    /// \e
   3.571 +    void setColCoeffs(Col col, const DualExpression& expr) {
   3.572 +      std::vector<std::pair<int, _Value> > col_coeffs;
   3.573 +      for(typename DualExpression::Data::const_iterator i=expr.data.begin(); 
   3.574 +	  i!=expr.data.end(); ++i) {
   3.575 +	col_coeffs.push_back(std::make_pair
   3.576 +			     (row_iter_map[(*i).first], (*i).second));
   3.577 +      }
   3.578 +      _setColCoeffs(col_iter_map[col], col_coeffs);
   3.579 +    }
   3.580 +    /// \e
   3.581 +    /// This routine modifies \c expr by only adding to it.
   3.582 +    void getColCoeffs(Col col, DualExpression& expr) {
   3.583 +      std::vector<std::pair<int, _Value> > col_coeffs;
   3.584 +      _getColCoeffs(col_iter_map[col], col_coeffs);
   3.585 +      for(typename std::vector<std::pair<int, _Value> >::const_iterator 
   3.586 + 	    i=col_coeffs.begin(); i!=col_coeffs.end(); ++i) {
   3.587 + 	expr+= (*i).second*int_row_map[(*i).first];
   3.588 +      }
   3.589 +    }
   3.590 +    /// \e
   3.591 +    void setObjCoeffs(const Expression& expr) {
   3.592 +      // writing zero everywhere
   3.593 +      for(Cols::ClassIt it(col_iter_map, VALID_CLASS); it!=INVALID; ++it)
   3.594 +	setObjCoeff(it, 0.0);
   3.595 +      // writing the data needed
   3.596 +      for(typename Expression::Data::const_iterator i=expr.data.begin(); 
   3.597 +	  i!=expr.data.end(); ++i) {
   3.598 +	setObjCoeff((*i).first, (*i).second);
   3.599 +      }
   3.600 +    }
   3.601 +    /// \e
   3.602 +    /// This routine modifies \c expr by only adding to it.
   3.603 +    void getObjCoeffs(Expression& expr) {
   3.604 +      for(Cols::ClassIt it(col_iter_map, VALID_CLASS); it!=INVALID; ++it)
   3.605 +	expr+=getObjCoeff(it)*it;
   3.606 +    }
   3.607 +    //@}
   3.608 +
   3.609 +
   3.610 +    /*! @name MIP functions and types (public members)
   3.611 +    */
   3.612 +    //@{
   3.613 +  public:
   3.614 +    /// \e
   3.615 +    virtual void solveBandB() = 0;
   3.616 +    /// \e
   3.617 +    virtual void setLP() = 0;
   3.618 +    /// \e
   3.619 +    virtual void setMIP() = 0;
   3.620 +  protected:
   3.621 +   /// \e
   3.622 +    virtual void _setColCont(int i) = 0;
   3.623 +    /// \e
   3.624 +    virtual void _setColInt(int i) = 0;
   3.625 +    /// \e
   3.626 +    virtual _Value _getMIPPrimal(int i) = 0;
   3.627 +  public:
   3.628 +    /// \e
   3.629 +    void setColCont(Col col) {
   3.630 +      _setColCont(col_iter_map[col]);
   3.631 +    }
   3.632 +    /// \e
   3.633 +    void setColInt(Col col) {
   3.634 +      _setColInt(col_iter_map[col]);
   3.635 +    }
   3.636 +    /// \e
   3.637 +    _Value getMIPPrimal(Col col) {
   3.638 +      return _getMIPPrimal(col_iter_map[col]);
   3.639 +    }
   3.640 +    //@}
   3.641 +  };
   3.642 +  
   3.643 +  template <typename _Value>
   3.644 +  const _Value LPSolverBase<_Value>::INF=std::numeric_limits<_Value>::infinity();
   3.645 +
   3.646 +
   3.647 +  /// \brief Wrapper for GLPK solver
   3.648 +  /// 
   3.649 +  /// This class implements a lemon wrapper for GLPK.
   3.650 +  class LPGLPK : public LPSolverBase<double> {
   3.651 +  public:
   3.652 +    typedef LPSolverBase<double> Parent;
   3.653 +
   3.654 +  public:
   3.655 +    /// \e
   3.656 +    LPX* lp;
   3.657 +
   3.658 +  public:
   3.659 +    /// \e
   3.660 +    LPGLPK() : Parent(), 
   3.661 +			lp(lpx_create_prob()) {
   3.662 +      int_row_map.push_back(Row());
   3.663 +      int_col_map.push_back(Col());
   3.664 +      lpx_set_int_parm(lp, LPX_K_DUAL, 1);
   3.665 +    }
   3.666 +    /// \e
   3.667 +    ~LPGLPK() {
   3.668 +      lpx_delete_prob(lp);
   3.669 +    }
   3.670 +
   3.671 +    //MATRIX INDEPEDENT MANIPULATING FUNCTIONS
   3.672 +
   3.673 +    /// \e
   3.674 +    void setMinimize() { 
   3.675 +      lpx_set_obj_dir(lp, LPX_MIN);
   3.676 +    }
   3.677 +    /// \e
   3.678 +    void setMaximize() { 
   3.679 +      lpx_set_obj_dir(lp, LPX_MAX);
   3.680 +    }
   3.681 +
   3.682 +    //LOW LEVEL INTERFACE, MATRIX MANIPULATING FUNCTIONS
   3.683 +
   3.684 +  protected:
   3.685 +    /// \e
   3.686 +    int _addCol() { 
   3.687 +      int i=lpx_add_cols(lp, 1);
   3.688 +      _setColLowerBound(i, -INF);
   3.689 +      _setColUpperBound(i, INF);
   3.690 +      return i;
   3.691 +    }
   3.692 +    /// \e
   3.693 +    int _addRow() { 
   3.694 +      int i=lpx_add_rows(lp, 1);
   3.695 +      return i;
   3.696 +    }
   3.697 +    /// \e
   3.698 +    virtual void _setRowCoeffs(int i, 
   3.699 +			       const std::vector<std::pair<int, double> >& coeffs) {
   3.700 +      int mem_length=1+colNum();
   3.701 +      int* indices = new int[mem_length];
   3.702 +      double* doubles = new double[mem_length];
   3.703 +      int length=0;
   3.704 +      for (std::vector<std::pair<int, double> >::
   3.705 +	     const_iterator it=coeffs.begin(); it!=coeffs.end(); ++it) {
   3.706 +	++length;
   3.707 +	indices[length]=it->first;
   3.708 +	doubles[length]=it->second;
   3.709 +      }
   3.710 +      lpx_set_mat_row(lp, i, length, indices, doubles);
   3.711 +      delete [] indices;
   3.712 +      delete [] doubles;
   3.713 +    }
   3.714 +    /// \e
   3.715 +    virtual void _getRowCoeffs(int i, 
   3.716 +			       std::vector<std::pair<int, double> >& coeffs) {
   3.717 +      int mem_length=1+colNum();
   3.718 +      int* indices = new int[mem_length];
   3.719 +      double* doubles = new double[mem_length];
   3.720 +      int length=lpx_get_mat_row(lp, i, indices, doubles);
   3.721 +      for (int i=1; i<=length; ++i) {
   3.722 +	coeffs.push_back(std::make_pair(indices[i], doubles[i]));
   3.723 +      }
   3.724 +      delete [] indices;
   3.725 +      delete [] doubles;
   3.726 +    }
   3.727 +    /// \e
   3.728 +    virtual void _setColCoeffs(int i, 
   3.729 +			       const std::vector<std::pair<int, double> >& coeffs) {
   3.730 +      int mem_length=1+rowNum();
   3.731 +      int* indices = new int[mem_length];
   3.732 +      double* doubles = new double[mem_length];
   3.733 +      int length=0;
   3.734 +      for (std::vector<std::pair<int, double> >::
   3.735 +	     const_iterator it=coeffs.begin(); it!=coeffs.end(); ++it) {
   3.736 +	++length;
   3.737 +	indices[length]=it->first;
   3.738 +	doubles[length]=it->second;
   3.739 +      }
   3.740 +      lpx_set_mat_col(lp, i, length, indices, doubles);
   3.741 +      delete [] indices;
   3.742 +      delete [] doubles;
   3.743 +    }
   3.744 +    /// \e
   3.745 +    virtual void _getColCoeffs(int i, 
   3.746 +			       std::vector<std::pair<int, double> >& coeffs) {
   3.747 +      int mem_length=1+rowNum();
   3.748 +      int* indices = new int[mem_length];
   3.749 +      double* doubles = new double[mem_length];
   3.750 +      int length=lpx_get_mat_col(lp, i, indices, doubles);
   3.751 +      for (int i=1; i<=length; ++i) {
   3.752 +	coeffs.push_back(std::make_pair(indices[i], doubles[i]));
   3.753 +      }
   3.754 +      delete [] indices;
   3.755 +      delete [] doubles;
   3.756 +    }
   3.757 +    /// \e
   3.758 +    virtual void _eraseCol(int i) {
   3.759 +      int cols[2];
   3.760 +      cols[1]=i;
   3.761 +      lpx_del_cols(lp, 1, cols);
   3.762 +    }
   3.763 +    virtual void _eraseRow(int i) {
   3.764 +      int rows[2];
   3.765 +      rows[1]=i;
   3.766 +      lpx_del_rows(lp, 1, rows);
   3.767 +    }
   3.768 +    void _setCoeff(int col, int row, double value) {
   3.769 +      /// FIXME not yet implemented
   3.770 +    }
   3.771 +    double _getCoeff(int col, int row) {
   3.772 +      /// FIXME not yet implemented
   3.773 +      return 0.0;
   3.774 +    }
   3.775 +    virtual void _setColLowerBound(int i, double lo) {
   3.776 +      if (lo==INF) {
   3.777 +	//FIXME error
   3.778 +      }
   3.779 +      int b=lpx_get_col_type(lp, i);
   3.780 +      double up=lpx_get_col_ub(lp, i);	
   3.781 +      if (lo==-INF) {
   3.782 +	switch (b) {
   3.783 +	case LPX_FR:
   3.784 +	case LPX_LO:
   3.785 +	  lpx_set_col_bnds(lp, i, LPX_FR, lo, up);
   3.786 +	  break;
   3.787 +	case LPX_UP:
   3.788 +	  break;
   3.789 +	case LPX_DB:
   3.790 +	case LPX_FX:
   3.791 +	  lpx_set_col_bnds(lp, i, LPX_UP, lo, up);
   3.792 +	  break;
   3.793 +	default: ;
   3.794 +	  //FIXME error
   3.795 +	}
   3.796 +      } else {
   3.797 +	switch (b) {
   3.798 +	case LPX_FR:
   3.799 +	case LPX_LO:
   3.800 +	  lpx_set_col_bnds(lp, i, LPX_LO, lo, up);
   3.801 +	  break;
   3.802 +	case LPX_UP:	  
   3.803 +	case LPX_DB:
   3.804 +	case LPX_FX:
   3.805 +	  if (lo==up) 
   3.806 +	    lpx_set_col_bnds(lp, i, LPX_FX, lo, up);
   3.807 +	  else 
   3.808 +	    lpx_set_col_bnds(lp, i, LPX_DB, lo, up);
   3.809 +	  break;
   3.810 +	default: ;
   3.811 +	  //FIXME error
   3.812 +	}
   3.813 +      }
   3.814 +    }
   3.815 +    virtual double _getColLowerBound(int i) {
   3.816 +      int b=lpx_get_col_type(lp, i);
   3.817 +      switch (b) {
   3.818 +      case LPX_FR:
   3.819 +	return -INF;
   3.820 +      case LPX_LO:
   3.821 +	return lpx_get_col_lb(lp, i);
   3.822 +      case LPX_UP:
   3.823 +	return -INF;
   3.824 +      case LPX_DB:
   3.825 +      case LPX_FX:
   3.826 +	return lpx_get_col_lb(lp, i);
   3.827 +      default: ;
   3.828 +	//FIXME error
   3.829 +	return 0.0;
   3.830 +      }
   3.831 +    }
   3.832 +    virtual void _setColUpperBound(int i, double up) {
   3.833 +      if (up==-INF) {
   3.834 +	//FIXME error
   3.835 +      }
   3.836 +      int b=lpx_get_col_type(lp, i);
   3.837 +      double lo=lpx_get_col_lb(lp, i);
   3.838 +      if (up==INF) {
   3.839 +	switch (b) {
   3.840 +	case LPX_FR:
   3.841 +	case LPX_LO:
   3.842 +	  break;
   3.843 +	case LPX_UP:
   3.844 +	  lpx_set_col_bnds(lp, i, LPX_FR, lo, up);
   3.845 +	  break;
   3.846 +	case LPX_DB:
   3.847 +	case LPX_FX:
   3.848 +	  lpx_set_col_bnds(lp, i, LPX_LO, lo, up);
   3.849 +	  break;
   3.850 +	default: ;
   3.851 +	  //FIXME error
   3.852 +	}
   3.853 +      } else {
   3.854 +	switch (b) {
   3.855 +	case LPX_FR:
   3.856 +	  lpx_set_col_bnds(lp, i, LPX_UP, lo, up);
   3.857 +	case LPX_LO:
   3.858 +	  if (lo==up) 
   3.859 +	    lpx_set_col_bnds(lp, i, LPX_FX, lo, up);
   3.860 +	  else
   3.861 +	    lpx_set_col_bnds(lp, i, LPX_DB, lo, up);
   3.862 +	  break;
   3.863 +	case LPX_UP:
   3.864 +	  lpx_set_col_bnds(lp, i, LPX_UP, lo, up);
   3.865 +	  break;
   3.866 +	case LPX_DB:
   3.867 +	case LPX_FX:
   3.868 +	  if (lo==up) 
   3.869 +	    lpx_set_col_bnds(lp, i, LPX_FX, lo, up);
   3.870 +	  else 
   3.871 +	    lpx_set_col_bnds(lp, i, LPX_DB, lo, up);
   3.872 +	  break;
   3.873 +	default: ;
   3.874 +	  //FIXME error
   3.875 +	}
   3.876 +      }
   3.877 +    }
   3.878 +    virtual double _getColUpperBound(int i) {
   3.879 +      int b=lpx_get_col_type(lp, i);
   3.880 +      switch (b) {
   3.881 +      case LPX_FR:
   3.882 +      case LPX_LO:
   3.883 +	return INF;
   3.884 +      case LPX_UP:
   3.885 +      case LPX_DB:
   3.886 +      case LPX_FX:
   3.887 +	return lpx_get_col_ub(lp, i);
   3.888 +      default: ;
   3.889 +	//FIXME error
   3.890 +	return 0.0;
   3.891 +      }
   3.892 +    }
   3.893 +    virtual void _setRowLowerBound(int i, double lo) {
   3.894 +      if (lo==INF) {
   3.895 +	//FIXME error
   3.896 +      }
   3.897 +      int b=lpx_get_row_type(lp, i);
   3.898 +      double up=lpx_get_row_ub(lp, i);	
   3.899 +      if (lo==-INF) {
   3.900 +	switch (b) {
   3.901 +	case LPX_FR:
   3.902 +	case LPX_LO:
   3.903 +	  lpx_set_row_bnds(lp, i, LPX_FR, lo, up);
   3.904 +	  break;
   3.905 +	case LPX_UP:
   3.906 +	  break;
   3.907 +	case LPX_DB:
   3.908 +	case LPX_FX:
   3.909 +	  lpx_set_row_bnds(lp, i, LPX_UP, lo, up);
   3.910 +	  break;
   3.911 +	default: ;
   3.912 +	  //FIXME error
   3.913 +	}
   3.914 +      } else {
   3.915 +	switch (b) {
   3.916 +	case LPX_FR:
   3.917 +	case LPX_LO:
   3.918 +	  lpx_set_row_bnds(lp, i, LPX_LO, lo, up);
   3.919 +	  break;
   3.920 +	case LPX_UP:	  
   3.921 +	case LPX_DB:
   3.922 +	case LPX_FX:
   3.923 +	  if (lo==up) 
   3.924 +	    lpx_set_row_bnds(lp, i, LPX_FX, lo, up);
   3.925 +	  else 
   3.926 +	    lpx_set_row_bnds(lp, i, LPX_DB, lo, up);
   3.927 +	  break;
   3.928 +	default: ;
   3.929 +	  //FIXME error
   3.930 +	}
   3.931 +      }
   3.932 +    }
   3.933 +    virtual double _getRowLowerBound(int i) {
   3.934 +      int b=lpx_get_row_type(lp, i);
   3.935 +      switch (b) {
   3.936 +      case LPX_FR:
   3.937 +	return -INF;
   3.938 +      case LPX_LO:
   3.939 +	return lpx_get_row_lb(lp, i);
   3.940 +      case LPX_UP:
   3.941 +	return -INF;
   3.942 +      case LPX_DB:
   3.943 +      case LPX_FX:
   3.944 +	return lpx_get_row_lb(lp, i);
   3.945 +      default: ;
   3.946 +	//FIXME error
   3.947 +	return 0.0;
   3.948 +      }
   3.949 +    }
   3.950 +    virtual void _setRowUpperBound(int i, double up) {
   3.951 +      if (up==-INF) {
   3.952 +	//FIXME error
   3.953 +      }
   3.954 +      int b=lpx_get_row_type(lp, i);
   3.955 +      double lo=lpx_get_row_lb(lp, i);
   3.956 +      if (up==INF) {
   3.957 +	switch (b) {
   3.958 +	case LPX_FR:
   3.959 +	case LPX_LO:
   3.960 +	  break;
   3.961 +	case LPX_UP:
   3.962 +	  lpx_set_row_bnds(lp, i, LPX_FR, lo, up);
   3.963 +	  break;
   3.964 +	case LPX_DB:
   3.965 +	case LPX_FX:
   3.966 +	  lpx_set_row_bnds(lp, i, LPX_LO, lo, up);
   3.967 +	  break;
   3.968 +	default: ;
   3.969 +	  //FIXME error
   3.970 +	}
   3.971 +      } else {
   3.972 +	switch (b) {
   3.973 +	case LPX_FR:
   3.974 +	  lpx_set_row_bnds(lp, i, LPX_UP, lo, up);
   3.975 +	case LPX_LO:
   3.976 +	  if (lo==up) 
   3.977 +	    lpx_set_row_bnds(lp, i, LPX_FX, lo, up);
   3.978 +	  else
   3.979 +	    lpx_set_row_bnds(lp, i, LPX_DB, lo, up);
   3.980 +	  break;
   3.981 +	case LPX_UP:
   3.982 +	  lpx_set_row_bnds(lp, i, LPX_UP, lo, up);
   3.983 +	  break;
   3.984 +	case LPX_DB:
   3.985 +	case LPX_FX:
   3.986 +	  if (lo==up) 
   3.987 +	    lpx_set_row_bnds(lp, i, LPX_FX, lo, up);
   3.988 +	  else 
   3.989 +	    lpx_set_row_bnds(lp, i, LPX_DB, lo, up);
   3.990 +	  break;
   3.991 +	default: ;
   3.992 +	  //FIXME error
   3.993 +	}
   3.994 +      }
   3.995 +    }
   3.996 +    virtual double _getRowUpperBound(int i) {
   3.997 +      int b=lpx_get_row_type(lp, i);
   3.998 +      switch (b) {
   3.999 +      case LPX_FR:
  3.1000 +      case LPX_LO:
  3.1001 +	return INF;
  3.1002 +      case LPX_UP:
  3.1003 +      case LPX_DB:
  3.1004 +      case LPX_FX:
  3.1005 +	return lpx_get_row_ub(lp, i);
  3.1006 +      default: ;
  3.1007 +	//FIXME error
  3.1008 +	return 0.0;
  3.1009 +      }
  3.1010 +    }
  3.1011 +    /// \e
  3.1012 +    virtual double _getObjCoeff(int i) { 
  3.1013 +      return lpx_get_obj_coef(lp, i);
  3.1014 +    }
  3.1015 +    /// \e
  3.1016 +    virtual void _setObjCoeff(int i, double obj_coef) { 
  3.1017 +      lpx_set_obj_coef(lp, i, obj_coef);
  3.1018 +    }
  3.1019 +  public:
  3.1020 +    /// \e
  3.1021 +    void solveSimplex() { lpx_simplex(lp); }
  3.1022 +    /// \e
  3.1023 +    void solvePrimalSimplex() { lpx_simplex(lp); }
  3.1024 +    /// \e
  3.1025 +    void solveDualSimplex() { lpx_simplex(lp); }
  3.1026 +  protected:
  3.1027 +    virtual double _getPrimal(int i) {
  3.1028 +      return lpx_get_col_prim(lp, i);
  3.1029 +    }
  3.1030 +  public:
  3.1031 +    /// \e
  3.1032 +    double getObjVal() { return lpx_get_obj_val(lp); }
  3.1033 +    /// \e
  3.1034 +    int rowNum() const { return lpx_get_num_rows(lp); }
  3.1035 +    /// \e
  3.1036 +    int colNum() const { return lpx_get_num_cols(lp); }
  3.1037 +    /// \e
  3.1038 +    int warmUp() { return lpx_warm_up(lp); }
  3.1039 +    /// \e
  3.1040 +    void printWarmUpStatus(int i) {
  3.1041 +      switch (i) {
  3.1042 +      case LPX_E_OK: cout << "LPX_E_OK" << endl; break;
  3.1043 +      case LPX_E_EMPTY: cout << "LPX_E_EMPTY" << endl; break;	
  3.1044 +      case LPX_E_BADB: cout << "LPX_E_BADB" << endl; break;
  3.1045 +      case LPX_E_SING: cout << "LPX_E_SING" << endl; break;
  3.1046 +      }
  3.1047 +    }
  3.1048 +    /// \e
  3.1049 +    int getPrimalStatus() { return lpx_get_prim_stat(lp); }
  3.1050 +    /// \e
  3.1051 +    void printPrimalStatus(int i) {
  3.1052 +      switch (i) {
  3.1053 +      case LPX_P_UNDEF: cout << "LPX_P_UNDEF" << endl; break;
  3.1054 +      case LPX_P_FEAS: cout << "LPX_P_FEAS" << endl; break;	
  3.1055 +      case LPX_P_INFEAS: cout << "LPX_P_INFEAS" << endl; break;
  3.1056 +      case LPX_P_NOFEAS: cout << "LPX_P_NOFEAS" << endl; break;
  3.1057 +      }
  3.1058 +    }
  3.1059 +    /// \e
  3.1060 +    int getDualStatus() { return lpx_get_dual_stat(lp); }
  3.1061 +    /// \e
  3.1062 +    void printDualStatus(int i) {
  3.1063 +      switch (i) {
  3.1064 +      case LPX_D_UNDEF: cout << "LPX_D_UNDEF" << endl; break;
  3.1065 +      case LPX_D_FEAS: cout << "LPX_D_FEAS" << endl; break;	
  3.1066 +      case LPX_D_INFEAS: cout << "LPX_D_INFEAS" << endl; break;
  3.1067 +      case LPX_D_NOFEAS: cout << "LPX_D_NOFEAS" << endl; break;
  3.1068 +      }
  3.1069 +    }
  3.1070 +    /// Returns the status of the slack variable assigned to row \c row.
  3.1071 +    int getRowStat(const Row& row) { 
  3.1072 +      return lpx_get_row_stat(lp, row_iter_map[row]); 
  3.1073 +    }
  3.1074 +    /// \e
  3.1075 +    void printRowStatus(int i) {
  3.1076 +      switch (i) {
  3.1077 +      case LPX_BS: cout << "LPX_BS" << endl; break;
  3.1078 +      case LPX_NL: cout << "LPX_NL" << endl; break;	
  3.1079 +      case LPX_NU: cout << "LPX_NU" << endl; break;
  3.1080 +      case LPX_NF: cout << "LPX_NF" << endl; break;
  3.1081 +      case LPX_NS: cout << "LPX_NS" << endl; break;
  3.1082 +      }
  3.1083 +    }
  3.1084 +    /// Returns the status of the variable assigned to column \c col.
  3.1085 +    int getColStat(const Col& col) { 
  3.1086 +      return lpx_get_col_stat(lp, col_iter_map[col]); 
  3.1087 +    }
  3.1088 +    /// \e
  3.1089 +    void printColStatus(int i) {
  3.1090 +      switch (i) {
  3.1091 +      case LPX_BS: cout << "LPX_BS" << endl; break;
  3.1092 +      case LPX_NL: cout << "LPX_NL" << endl; break;	
  3.1093 +      case LPX_NU: cout << "LPX_NU" << endl; break;
  3.1094 +      case LPX_NF: cout << "LPX_NF" << endl; break;
  3.1095 +      case LPX_NS: cout << "LPX_NS" << endl; break;
  3.1096 +      }
  3.1097 +    }
  3.1098 +
  3.1099 +    // MIP
  3.1100 +    /// \e
  3.1101 +    void solveBandB() { lpx_integer(lp); }
  3.1102 +    /// \e
  3.1103 +    void setLP() { lpx_set_class(lp, LPX_LP); }
  3.1104 +    /// \e
  3.1105 +    void setMIP() { lpx_set_class(lp, LPX_MIP); }
  3.1106 +  protected:
  3.1107 +    /// \e
  3.1108 +    void _setColCont(int i) { lpx_set_col_kind(lp, i, LPX_CV); }
  3.1109 +    /// \e
  3.1110 +    void _setColInt(int i) { lpx_set_col_kind(lp, i, LPX_IV); }
  3.1111 +    /// \e
  3.1112 +    double _getMIPPrimal(int i) { return lpx_mip_col_val(lp, i); }
  3.1113 +  };
  3.1114 +  
  3.1115 +  /// @}
  3.1116 +
  3.1117 +} //namespace lemon
  3.1118 +
  3.1119 +#endif //LEMON_LP_SOLVER_BASE_H
     4.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     4.2 +++ b/src/work/athos/lp/lp_solver_wrapper.h	Tue Mar 22 11:45:47 2005 +0000
     4.3 @@ -0,0 +1,431 @@
     4.4 +// -*- c++ -*-
     4.5 +#ifndef LEMON_LP_SOLVER_WRAPPER_H
     4.6 +#define LEMON_LP_SOLVER_WRAPPER_H
     4.7 +
     4.8 +///\ingroup misc
     4.9 +///\file
    4.10 +///\brief Dijkstra algorithm.
    4.11 +
    4.12 +// #include <stdio.h>
    4.13 +#include <stdlib.h>
    4.14 +// #include <stdio>
    4.15 +//#include <stdlib>
    4.16 +extern "C" {
    4.17 +#include "glpk.h"
    4.18 +}
    4.19 +
    4.20 +#include <iostream>
    4.21 +#include <vector>
    4.22 +#include <string>
    4.23 +#include <list>
    4.24 +#include <memory>
    4.25 +#include <utility>
    4.26 +
    4.27 +//#include <sage_graph.h>
    4.28 +//#include <lemon/list_graph.h>
    4.29 +//#include <lemon/graph_wrapper.h>
    4.30 +#include <lemon/invalid.h>
    4.31 +//#include <bfs_dfs.h>
    4.32 +//#include <stp.h>
    4.33 +//#include <lemon/max_flow.h>
    4.34 +//#include <augmenting_flow.h>
    4.35 +//#include <iter_map.h>
    4.36 +
    4.37 +using std::cout;
    4.38 +using std::cin;
    4.39 +using std::endl;
    4.40 +
    4.41 +namespace lemon {
    4.42 +
    4.43 +  
    4.44 +  /// \addtogroup misc
    4.45 +  /// @{
    4.46 +
    4.47 +  /// \brief A partitioned vector with iterable classes.
    4.48 +  ///
    4.49 +  /// This class implements a container in which the data is stored in an 
    4.50 +  /// stl vector, the range is partitioned into sets and each set is 
    4.51 +  /// doubly linked in a list. 
    4.52 +  /// That is, each class is iterable by lemon iterators, and any member of 
    4.53 +  /// the vector can bo moved to an other class.
    4.54 +  template <typename T>
    4.55 +  class IterablePartition {
    4.56 +  protected:
    4.57 +    struct Node {
    4.58 +      T data;
    4.59 +      int prev; //invalid az -1
    4.60 +      int next; 
    4.61 +    };
    4.62 +    std::vector<Node> nodes;
    4.63 +    struct Tip {
    4.64 +      int first;
    4.65 +      int last;
    4.66 +    };
    4.67 +    std::vector<Tip> tips;
    4.68 +  public:
    4.69 +    /// The classes are indexed by integers from \c 0 to \c classNum()-1.
    4.70 +    int classNum() const { return tips.size(); }
    4.71 +    /// This lemon style iterator iterates through a class. 
    4.72 +    class ClassIt;
    4.73 +    /// Constructor. The number of classes is to be given which is fixed 
    4.74 +    /// over the life of the container. 
    4.75 +    /// The partition classes are indexed from 0 to class_num-1. 
    4.76 +    IterablePartition(int class_num) { 
    4.77 +      for (int i=0; i<class_num; ++i) {
    4.78 +	Tip t;
    4.79 +	t.first=t.last=-1;
    4.80 +	tips.push_back(t);
    4.81 +      }
    4.82 +    }
    4.83 +  protected:
    4.84 +    void befuz(ClassIt it, int class_id) {
    4.85 +      if (tips[class_id].first==-1) {
    4.86 +	if (tips[class_id].last==-1) {
    4.87 +	  nodes[it.i].prev=nodes[it.i].next=-1;
    4.88 +	  tips[class_id].first=tips[class_id].last=it.i;
    4.89 +	}
    4.90 +      } else {
    4.91 +	nodes[it.i].prev=tips[class_id].last;
    4.92 +	nodes[it.i].next=-1;
    4.93 +	nodes[tips[class_id].last].next=it.i;
    4.94 +	tips[class_id].last=it.i;
    4.95 +      }
    4.96 +    }
    4.97 +    void kifuz(ClassIt it, int class_id) {
    4.98 +      if (tips[class_id].first==it.i) {
    4.99 +	if (tips[class_id].last==it.i) {
   4.100 +	  tips[class_id].first=tips[class_id].last=-1;
   4.101 +	} else {
   4.102 +	  tips[class_id].first=nodes[it.i].next;
   4.103 +	  nodes[nodes[it.i].next].prev=-1;
   4.104 +	}
   4.105 +      } else {
   4.106 +	if (tips[class_id].last==it.i) {
   4.107 +	  tips[class_id].last=nodes[it.i].prev;
   4.108 +	  nodes[nodes[it.i].prev].next=-1;
   4.109 +	} else {
   4.110 +	  nodes[nodes[it.i].next].prev=nodes[it.i].prev;
   4.111 +	  nodes[nodes[it.i].prev].next=nodes[it.i].next;
   4.112 +	}
   4.113 +      }
   4.114 +    }
   4.115 +  public:
   4.116 +    /// A new element with data \c t is pushed into the vector and into class 
   4.117 +    /// \c class_id.
   4.118 +    ClassIt push_back(const T& t, int class_id) { 
   4.119 +      Node n;
   4.120 +      n.data=t;
   4.121 +      nodes.push_back(n);
   4.122 +      int i=nodes.size()-1;
   4.123 +      befuz(i, class_id);
   4.124 +      return i;
   4.125 +    }
   4.126 +    /// A member is moved to an other class.
   4.127 +    void set(ClassIt it, int old_class_id, int new_class_id) {
   4.128 +      kifuz(it.i, old_class_id);
   4.129 +      befuz(it.i, new_class_id);
   4.130 +    }
   4.131 +    /// Returns the data pointed by \c it.
   4.132 +    T& operator[](ClassIt it) { return nodes[it.i].data; }
   4.133 +    /// Returns the data pointed by \c it.
   4.134 +    const T& operator[](ClassIt it) const { return nodes[it.i].data; }
   4.135 +    ///.
   4.136 +    class ClassIt {
   4.137 +      friend class IterablePartition;
   4.138 +    protected:
   4.139 +      int i;
   4.140 +    public:
   4.141 +      /// Default constructor.
   4.142 +      ClassIt() { }
   4.143 +      /// This constructor constructs an iterator which points
   4.144 +      /// to the member of th container indexed by the integer _i.
   4.145 +      ClassIt(const int& _i) : i(_i) { }
   4.146 +      /// Invalid constructor.
   4.147 +      ClassIt(const Invalid&) : i(-1) { }
   4.148 +    };
   4.149 +    /// First member of class \c class_id.
   4.150 +    ClassIt& first(ClassIt& it, int class_id) const {
   4.151 +      it.i=tips[class_id].first;
   4.152 +      return it;
   4.153 +    }
   4.154 +    /// Next member.
   4.155 +    ClassIt& next(ClassIt& it) const {
   4.156 +      it.i=nodes[it.i].next;
   4.157 +      return it;
   4.158 +    }
   4.159 +    /// True iff the iterator is valid.
   4.160 +    bool valid(const ClassIt& it) const { return it.i!=-1; }
   4.161 +  };
   4.162 +  
   4.163 +  /// \brief Wrappers for LP solvers
   4.164 +  /// 
   4.165 +  /// This class implements a lemon wrapper for glpk.
   4.166 +  /// Later other LP-solvers will be wrapped into lemon.
   4.167 +  /// The aim of this class is to give a general surface to different 
   4.168 +  /// solvers, i.e. it makes possible to write algorithms using LP's, 
   4.169 +  /// in which the solver can be changed to an other one easily.
   4.170 +  class LPSolverWrapper {
   4.171 +  public:
   4.172 +
   4.173 +//   class Row {
   4.174 +//   protected:
   4.175 +//     int i;
   4.176 +//   public:
   4.177 +//     Row() { }
   4.178 +//     Row(const Invalid&) : i(0) { }
   4.179 +//     Row(const int& _i) : i(_i) { }
   4.180 +//     operator int() const { return i; }
   4.181 +//   };
   4.182 +//   class RowIt : public Row {
   4.183 +//   public:
   4.184 +//     RowIt(const Row& row) : Row(row) { }
   4.185 +//   };
   4.186 +
   4.187 +//   class Col {
   4.188 +//   protected:
   4.189 +//     int i;
   4.190 +//   public:
   4.191 +//     Col() { }
   4.192 +//     Col(const Invalid&) : i(0) { }
   4.193 +//     Col(const int& _i) : i(_i) { }
   4.194 +//     operator int() const { return i; }
   4.195 +//   };
   4.196 +//   class ColIt : public Col {
   4.197 +//     ColIt(const Col& col) : Col(col) { }
   4.198 +//   };
   4.199 +
   4.200 +  public:
   4.201 +    ///.
   4.202 +    LPX* lp;
   4.203 +    ///.
   4.204 +    typedef IterablePartition<int>::ClassIt RowIt;
   4.205 +    ///.
   4.206 +    IterablePartition<int> row_iter_map;
   4.207 +    ///.
   4.208 +    typedef IterablePartition<int>::ClassIt ColIt;
   4.209 +    ///.
   4.210 +    IterablePartition<int> col_iter_map;
   4.211 +    //std::vector<int> row_id_to_lp_row_id;
   4.212 +    //std::vector<int> col_id_to_lp_col_id;
   4.213 +    ///.
   4.214 +    const int VALID_ID;
   4.215 +    ///.
   4.216 +    const int INVALID_ID;
   4.217 +
   4.218 +  public:
   4.219 +    ///.
   4.220 +    LPSolverWrapper() : lp(lpx_create_prob()), 
   4.221 +			row_iter_map(2), 
   4.222 +			col_iter_map(2), 
   4.223 +			//row_id_to_lp_row_id(), col_id_to_lp_col_id(), 
   4.224 +			VALID_ID(0), INVALID_ID(1) {
   4.225 +      lpx_set_int_parm(lp, LPX_K_DUAL, 1);
   4.226 +    }
   4.227 +    ///.
   4.228 +    ~LPSolverWrapper() {
   4.229 +      lpx_delete_prob(lp);
   4.230 +    }
   4.231 +    ///.
   4.232 +    void setMinimize() { 
   4.233 +      lpx_set_obj_dir(lp, LPX_MIN);
   4.234 +    }
   4.235 +    ///.
   4.236 +    void setMaximize() { 
   4.237 +      lpx_set_obj_dir(lp, LPX_MAX);
   4.238 +    }
   4.239 +    ///.
   4.240 +    ColIt addCol() {
   4.241 +      int i=lpx_add_cols(lp, 1);  
   4.242 +      ColIt col_it;
   4.243 +      col_iter_map.first(col_it, INVALID_ID);
   4.244 +      if (col_iter_map.valid(col_it)) { //van hasznalhato hely
   4.245 +	col_iter_map.set(col_it, INVALID_ID, VALID_ID);
   4.246 +	col_iter_map[col_it]=i;
   4.247 +	//col_id_to_lp_col_id[col_iter_map[col_it]]=i;
   4.248 +      } else { //a cucc vegere kell inzertalni mert nincs szabad hely
   4.249 +	//col_id_to_lp_col_id.push_back(i);
   4.250 +	//int j=col_id_to_lp_col_id.size()-1;
   4.251 +	col_it=col_iter_map.push_back(i, VALID_ID);
   4.252 +      }
   4.253 +//    edge_index_map.set(e, i);
   4.254 +//    lpx_set_col_bnds(lp, i, LPX_DB, 0.0, 1.0);
   4.255 +//    lpx_set_obj_coef(lp, i, cost[e]);    
   4.256 +      return col_it;
   4.257 +    }
   4.258 +    ///.
   4.259 +    RowIt addRow() {
   4.260 +      int i=lpx_add_rows(lp, 1);  
   4.261 +      RowIt row_it;
   4.262 +      row_iter_map.first(row_it, INVALID_ID);
   4.263 +      if (row_iter_map.valid(row_it)) { //van hasznalhato hely
   4.264 +	row_iter_map.set(row_it, INVALID_ID, VALID_ID);
   4.265 +	row_iter_map[row_it]=i;
   4.266 +      } else { //a cucc vegere kell inzertalni mert nincs szabad hely
   4.267 +	row_it=row_iter_map.push_back(i, VALID_ID);
   4.268 +      }
   4.269 +      return row_it;
   4.270 +    }
   4.271 +    //pair<RowIt, double>-bol kell megadni egy std range-et
   4.272 +    ///.
   4.273 +    template <typename Begin, typename End>
   4.274 +    void setColCoeffs(const ColIt& col_it, 
   4.275 +		      Begin begin, End end) {
   4.276 +      int mem_length=1+lpx_get_num_rows(lp);
   4.277 +      int* indices = new int[mem_length];
   4.278 +      double* doubles = new double[mem_length];
   4.279 +      int length=0;
   4.280 +      for ( ; begin!=end; ++begin) {
   4.281 +	++length;
   4.282 +	indices[length]=row_iter_map[begin->first];
   4.283 +	doubles[length]=begin->second;
   4.284 +      }
   4.285 +      lpx_set_mat_col(lp, col_iter_map[col_it], length, indices, doubles);
   4.286 +      delete [] indices;
   4.287 +      delete [] doubles;
   4.288 +    }
   4.289 +    //pair<ColIt, double>-bol kell megadni egy std range-et
   4.290 +    ///.
   4.291 +    template <typename Begin, typename End>
   4.292 +    void setRowCoeffs(const RowIt& row_it, 
   4.293 +		      Begin begin, End end) {
   4.294 +      int mem_length=1+lpx_get_num_cols(lp);
   4.295 +      int* indices = new int[mem_length];
   4.296 +      double* doubles = new double[mem_length];
   4.297 +      int length=0;
   4.298 +      for ( ; begin!=end; ++begin) {
   4.299 +	++length;
   4.300 +	indices[length]=col_iter_map[begin->first];
   4.301 +	doubles[length]=begin->second;
   4.302 +      }
   4.303 +      lpx_set_mat_row(lp, row_iter_map[row_it], length, indices, doubles);
   4.304 +      delete [] indices;
   4.305 +      delete [] doubles;
   4.306 +    }
   4.307 +    ///.
   4.308 +    void eraseCol(const ColIt& col_it) {
   4.309 +      col_iter_map.set(col_it, VALID_ID, INVALID_ID);
   4.310 +      int cols[2];
   4.311 +      cols[1]=col_iter_map[col_it];
   4.312 +      lpx_del_cols(lp, 1, cols);
   4.313 +      col_iter_map[col_it]=0; //glpk specifikus
   4.314 +      ColIt it;
   4.315 +      for (col_iter_map.first(it, VALID_ID); 
   4.316 +	   col_iter_map.valid(it); col_iter_map.next(it)) {
   4.317 +	if (col_iter_map[it]>cols[1]) --col_iter_map[it];
   4.318 +      }
   4.319 +    }
   4.320 +    ///.
   4.321 +    void eraseRow(const RowIt& row_it) {
   4.322 +      row_iter_map.set(row_it, VALID_ID, INVALID_ID);
   4.323 +      int rows[2];
   4.324 +      rows[1]=row_iter_map[row_it];
   4.325 +      lpx_del_rows(lp, 1, rows);
   4.326 +      row_iter_map[row_it]=0; //glpk specifikus
   4.327 +      RowIt it;
   4.328 +      for (row_iter_map.first(it, VALID_ID); 
   4.329 +	   row_iter_map.valid(it); row_iter_map.next(it)) {
   4.330 +	if (row_iter_map[it]>rows[1]) --row_iter_map[it];
   4.331 +      }
   4.332 +    }
   4.333 +    ///.
   4.334 +    void setColBounds(const ColIt& col_it, int bound_type, 
   4.335 +		      double lo, double up) {
   4.336 +      lpx_set_col_bnds(lp, col_iter_map[col_it], bound_type, lo, up);
   4.337 +    }
   4.338 +    ///.
   4.339 +    double getObjCoef(const ColIt& col_it) { 
   4.340 +      return lpx_get_obj_coef(lp, col_iter_map[col_it]);
   4.341 +    }
   4.342 +    ///.
   4.343 +    void setRowBounds(const RowIt& row_it, int bound_type, 
   4.344 +		      double lo, double up) {
   4.345 +      lpx_set_row_bnds(lp, row_iter_map[row_it], bound_type, lo, up);
   4.346 +    }
   4.347 +    ///.
   4.348 +    void setObjCoef(const ColIt& col_it, double obj_coef) { 
   4.349 +      lpx_set_obj_coef(lp, col_iter_map[col_it], obj_coef);
   4.350 +    }
   4.351 +    ///.
   4.352 +    void solveSimplex() { lpx_simplex(lp); }
   4.353 +    ///.
   4.354 +    void solvePrimalSimplex() { lpx_simplex(lp); }
   4.355 +    ///.
   4.356 +    void solveDualSimplex() { lpx_simplex(lp); }
   4.357 +    ///.
   4.358 +    double getPrimal(const ColIt& col_it) {
   4.359 +      return lpx_get_col_prim(lp, col_iter_map[col_it]);
   4.360 +    }
   4.361 +    ///.
   4.362 +    double getObjVal() { return lpx_get_obj_val(lp); }
   4.363 +    ///.
   4.364 +    int rowNum() const { return lpx_get_num_rows(lp); }
   4.365 +    ///.
   4.366 +    int colNum() const { return lpx_get_num_cols(lp); }
   4.367 +    ///.
   4.368 +    int warmUp() { return lpx_warm_up(lp); }
   4.369 +    ///.
   4.370 +    void printWarmUpStatus(int i) {
   4.371 +      switch (i) {
   4.372 +	case LPX_E_OK: cout << "LPX_E_OK" << endl; break;
   4.373 +	case LPX_E_EMPTY: cout << "LPX_E_EMPTY" << endl; break;	
   4.374 +	case LPX_E_BADB: cout << "LPX_E_BADB" << endl; break;
   4.375 +	case LPX_E_SING: cout << "LPX_E_SING" << endl; break;
   4.376 +      }
   4.377 +    }
   4.378 +    ///.
   4.379 +    int getPrimalStatus() { return lpx_get_prim_stat(lp); }
   4.380 +    ///.
   4.381 +    void printPrimalStatus(int i) {
   4.382 +      switch (i) {
   4.383 +	case LPX_P_UNDEF: cout << "LPX_P_UNDEF" << endl; break;
   4.384 +	case LPX_P_FEAS: cout << "LPX_P_FEAS" << endl; break;	
   4.385 +	case LPX_P_INFEAS: cout << "LPX_P_INFEAS" << endl; break;
   4.386 +	case LPX_P_NOFEAS: cout << "LPX_P_NOFEAS" << endl; break;
   4.387 +      }
   4.388 +    }
   4.389 +    ///.
   4.390 +    int getDualStatus() { return lpx_get_dual_stat(lp); }
   4.391 +    ///.
   4.392 +    void printDualStatus(int i) {
   4.393 +      switch (i) {
   4.394 +	case LPX_D_UNDEF: cout << "LPX_D_UNDEF" << endl; break;
   4.395 +	case LPX_D_FEAS: cout << "LPX_D_FEAS" << endl; break;	
   4.396 +	case LPX_D_INFEAS: cout << "LPX_D_INFEAS" << endl; break;
   4.397 +	case LPX_D_NOFEAS: cout << "LPX_D_NOFEAS" << endl; break;
   4.398 +      }
   4.399 +    }
   4.400 +    /// Returns the status of the slack variable assigned to row \c row_it.
   4.401 +    int getRowStat(const RowIt& row_it) { 
   4.402 +      return lpx_get_row_stat(lp, row_iter_map[row_it]); 
   4.403 +    }
   4.404 +    ///.
   4.405 +    void printRowStatus(int i) {
   4.406 +      switch (i) {
   4.407 +	case LPX_BS: cout << "LPX_BS" << endl; break;
   4.408 +	case LPX_NL: cout << "LPX_NL" << endl; break;	
   4.409 +	case LPX_NU: cout << "LPX_NU" << endl; break;
   4.410 +	case LPX_NF: cout << "LPX_NF" << endl; break;
   4.411 +	case LPX_NS: cout << "LPX_NS" << endl; break;
   4.412 +      }
   4.413 +    }
   4.414 +    /// Returns the status of the variable assigned to column \c col_it.
   4.415 +    int getColStat(const ColIt& col_it) { 
   4.416 +      return lpx_get_col_stat(lp, col_iter_map[col_it]); 
   4.417 +    }
   4.418 +    ///.
   4.419 +    void printColStatus(int i) {
   4.420 +      switch (i) {
   4.421 +	case LPX_BS: cout << "LPX_BS" << endl; break;
   4.422 +	case LPX_NL: cout << "LPX_NL" << endl; break;	
   4.423 +	case LPX_NU: cout << "LPX_NU" << endl; break;
   4.424 +	case LPX_NF: cout << "LPX_NF" << endl; break;
   4.425 +	case LPX_NS: cout << "LPX_NS" << endl; break;
   4.426 +      }
   4.427 +    }
   4.428 +  };
   4.429 +  
   4.430 +  /// @}
   4.431 +
   4.432 +} //namespace lemon
   4.433 +
   4.434 +#endif //LEMON_LP_SOLVER_WRAPPER_H
     5.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     5.2 +++ b/src/work/athos/lp/magic_square.cc	Tue Mar 22 11:45:47 2005 +0000
     5.3 @@ -0,0 +1,90 @@
     5.4 +// -*- c++ -*-
     5.5 +#include <iostream>
     5.6 +#include <fstream>
     5.7 +
     5.8 +#include <lemon/time_measure.h>
     5.9 +#include <lp_solver_base.h>
    5.10 +
    5.11 +using std::cout;
    5.12 +using std::endl;
    5.13 +using namespace lemon;
    5.14 +
    5.15 +/*
    5.16 +  On an 1537Mhz PC, the run times with 
    5.17 +  glpk are the following.
    5.18 +  for n=3,4, some secondes
    5.19 +  for n=5, 25 hours
    5.20 + */
    5.21 +
    5.22 +int main(int, char **) {
    5.23 +  const int n=4;
    5.24 +  const double row_sum=(1.0+n*n)*n/2;
    5.25 +  Timer ts;
    5.26 +  ts.reset();
    5.27 +  typedef LPGLPK LPSolver;
    5.28 +  typedef LPSolver::Col Col;
    5.29 +  LPSolver lp;
    5.30 +  typedef std::map<std::pair<int, int>, Col> Coords;
    5.31 +  Coords x;
    5.32 +  // we create a new variable for each entry 
    5.33 +  // of the magic square
    5.34 +  for (int i=1; i<=n; ++i) {
    5.35 +    for (int j=1; j<=n; ++j) { 
    5.36 +      Col col=lp.addCol();
    5.37 +      x[std::make_pair(i,j)]=col;
    5.38 +      lp.setColLowerBound(col, 1.0);
    5.39 +      lp.setColUpperBound(col, double(n*n));
    5.40 +    }
    5.41 +  }
    5.42 +  LPSolver::Expression expr3, expr4;
    5.43 +  for (int i=1; i<=n; ++i) {
    5.44 +    LPSolver::Expression expr1, expr2;
    5.45 +    for (int j=1; j<=n; ++j) {
    5.46 +      expr1+=x[std::make_pair(i, j)];
    5.47 +      expr2+=x[std::make_pair(j, i)];
    5.48 +    }
    5.49 +    // sum of rows and columns
    5.50 +    lp.addRow(expr1==row_sum);
    5.51 +    lp.addRow(expr2==row_sum);
    5.52 +    expr3+=x[std::make_pair(i, i)];
    5.53 +    expr4+=x[std::make_pair(i, (n+1)-i)];
    5.54 +  }
    5.55 +  // sum of the diagonal entries
    5.56 +  lp.addRow(expr3==row_sum);
    5.57 +  lp.addRow(expr4==row_sum);
    5.58 +  lp.solveSimplex();
    5.59 +  cout << "elapsed time: " << ts << endl;
    5.60 +  for (int i=1; i<=n; ++i) {
    5.61 +    for (int j=1; j<=n; ++j) { 
    5.62 +      cout << "x("<<i<<","<<j<<")="<<lp.getPrimal(x[std::make_pair(i,j)]) 
    5.63 +	   << endl;
    5.64 +    }
    5.65 +  }
    5.66 +  // we make new binary variables for each pair of 
    5.67 +  // entries of the square to achieve that 
    5.68 +  // the values of different entries are different
    5.69 +  lp.setMIP();
    5.70 +  for (Coords::const_iterator it=x.begin(); it!=x.end(); ++it) {
    5.71 +    Coords::const_iterator jt=it; ++jt;
    5.72 +    for(; jt!=x.end(); ++jt) {
    5.73 +      Col col1=(*it).second;
    5.74 +      Col col2=(*jt).second;
    5.75 +      Col col=lp.addCol();
    5.76 +      lp.setColLowerBound(col, 0.0);
    5.77 +      lp.setColUpperBound(col, 1.0);
    5.78 +      lp.addRow(double(-n*n+1.0)<=1.0*col2-1.0*col1-double(n*n)*col<=-1.0);
    5.79 +      lp.setColInt(col);
    5.80 +    }
    5.81 +  }
    5.82 +  cout << "elapsed time: " << ts << endl;
    5.83 +  lp.solveSimplex();
    5.84 +  // let's solve the integer problem
    5.85 +  lp.solveBandB();
    5.86 +  cout << "elapsed time: " << ts << endl;
    5.87 +  for (int i=1; i<=n; ++i) {
    5.88 +    for (int j=1; j<=n; ++j) { 
    5.89 +      cout << "x("<<i<<","<<j<<")="<<lp.getMIPPrimal(x[std::make_pair(i,j)]) 
    5.90 +	   << endl;
    5.91 +    }
    5.92 +  }
    5.93 +}
     6.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     6.2 +++ b/src/work/athos/lp/makefile	Tue Mar 22 11:45:47 2005 +0000
     6.3 @@ -0,0 +1,73 @@
     6.4 +#INCLUDEDIRS ?= -I.. -I. -I./{marci,jacint,alpar,klao,akos}
     6.5 +#GLPKROOT = /usr/local/glpk-4.4
     6.6 +INCLUDEDIRS ?= -I/home/marci/boost -I/usr/local/cplex/cplex75/include -I../../{marci,alpar,klao,akos,athos} -I. -I../../.. -I../.. -I..# -I$(GLPKROOT)/include
     6.7 +#INCLUDEDIRS ?= -I../.. -I../.. -I../../{marci,jacint,alpar,klao,akos} -I/usr/local/glpk-4.4/include
     6.8 +CXXFLAGS = -g -O2 -W -Wall $(INCLUDEDIRS) -ansi -pedantic
     6.9 +LDFLAGS  =  -lglpk#-lcplex -lm -lpthread -lilocplex -L/usr/local/cplex/cplex75/lib/i86_linux2_glibc2.2_gcc3.0/static_mt# -L$(GLPKROOT)/lib
    6.10 +
    6.11 +BINARIES = magic_square max_flow_expression expression_test max_flow_by_lp# sample sample2 sample11 sample15
    6.12 +
    6.13 +#include ../makefile
    6.14 +
    6.15 +# Hat, ez elismerem, hogy nagyon ronda, de mukodik minden altalam
    6.16 +# ismert rendszeren :-)  (Misi)
    6.17 +ifdef GCCVER
    6.18 +CXX := g++-$(GCCVER)
    6.19 +else
    6.20 +CXX := $(shell type -p g++-3.3 || type -p g++-3.2 || type -p g++-3.0 || type -p g++-3 || echo g++)
    6.21 +endif
    6.22 +
    6.23 +ifdef DEBUG
    6.24 +CXXFLAGS += -DDEBUG
    6.25 +endif
    6.26 +
    6.27 +CC := $(CXX)
    6.28 +
    6.29 +
    6.30 +all: $(BINARIES)
    6.31 +
    6.32 +################
    6.33 +# Minden binarishoz egy sor, felsorolva, hogy mely object file-okbol
    6.34 +# all elo.
    6.35 +# Kiveve ha siman file.cc -> file  esetrol van szo, amikor is nem kell
    6.36 +# irni semmit.
    6.37 +
    6.38 +#proba: proba.o seged.o
    6.39 +
    6.40 +################
    6.41 +
    6.42 +
    6.43 +# .depend dep depend:
    6.44 +# 	-$(CXX) $(CXXFLAGS) -M $(BINARIES:=.cc) > .depend
    6.45 +
    6.46 +#makefile: .depend
    6.47 +#sinclude .depend
    6.48 +#moert nem megy az eredeti /usr/bin/ld-vel?
    6.49 +
    6.50 +# %: %.o
    6.51 +# 	$(CXX) -o $@ $< $(LDFLAGS)
    6.52 +
    6.53 +# %.o: %.cc
    6.54 +# 	$(CXX) $(CXXFLAGS) -c $<
    6.55 +
    6.56 +%: %.cc
    6.57 +	$(CXX) $(CXXFLAGS) -o $@ $< $(LDFLAGS)
    6.58 +
    6.59 +sample11prof: sample11prof.o
    6.60 +	 $(CXX) -pg -o sample11prof sample11prof.o -L$(GLPKROOT)/lib -lglpk
    6.61 +sample11prof.o: sample11.cc
    6.62 +	$(CXX) -pg $(CXXFLAGS) -c -o sample11prof.o sample11.cc
    6.63 +
    6.64 +# sample.o: sample.cc
    6.65 +# 	$(CXX) $(CXXFLAGS) -c -o sample.o sample.cc
    6.66 +
    6.67 +# sample2: sample2.o
    6.68 +# 	$(CXX) -o sample2 sample2.o -L/usr/local/glpk-4.4/lib -lglpk
    6.69 +# sample2.o: sample2.cc
    6.70 +# 	$(CXX) $(CXXFLAGS) -c -o sample2.o sample2.cc
    6.71 +
    6.72 +
    6.73 +clean:
    6.74 +	$(RM) *.o $(BINARIES) .depend
    6.75 +
    6.76 +.PHONY: all clean dep depend
     7.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     7.2 +++ b/src/work/athos/lp/max_flow_by_lp.cc	Tue Mar 22 11:45:47 2005 +0000
     7.3 @@ -0,0 +1,186 @@
     7.4 +// -*- c++ -*-
     7.5 +#include <iostream>
     7.6 +#include <fstream>
     7.7 +
     7.8 +#include <lemon/smart_graph.h>
     7.9 +#include <lemon/list_graph.h>
    7.10 +#include <lemon/dimacs.h>
    7.11 +#include <lemon/time_measure.h>
    7.12 +//#include <graph_wrapper.h>
    7.13 +#include <lemon/preflow.h>
    7.14 +#include <augmenting_flow.h>
    7.15 +//#include <preflow_res.h>
    7.16 +//#include <lp_solver_wrapper_2.h>
    7.17 +#include <min_cost_gen_flow.h>
    7.18 +
    7.19 +// Use a DIMACS max flow file as stdin.
    7.20 +// max_flow_demo < dimacs_max_flow_file
    7.21 +
    7.22 +using namespace lemon;
    7.23 +
    7.24 +int main(int, char **) {
    7.25 +
    7.26 +  typedef ListGraph MutableGraph;
    7.27 +  typedef ListGraph Graph;
    7.28 +  typedef Graph::Node Node;
    7.29 +  typedef Graph::Edge Edge;
    7.30 +  typedef Graph::EdgeIt EdgeIt;
    7.31 +
    7.32 +  Graph g;
    7.33 +
    7.34 +  Node s, t;
    7.35 +  Graph::EdgeMap<int> cap(g);
    7.36 +  //readDimacsMaxFlow(std::cin, g, s, t, cap);
    7.37 +  readDimacs(std::cin, g, cap, s, t);
    7.38 +  Timer ts;
    7.39 +  Graph::EdgeMap<int> flow(g); //0 flow
    7.40 +  Preflow<Graph, int, Graph::EdgeMap<int>, Graph::EdgeMap<int> > 
    7.41 +    max_flow_test(g, s, t, cap, flow);
    7.42 +  AugmentingFlow<Graph, int, Graph::EdgeMap<int>, Graph::EdgeMap<int> > 
    7.43 +    augmenting_flow_test(g, s, t, cap, flow);
    7.44 +  
    7.45 +  Graph::NodeMap<bool> cut(g);
    7.46 +
    7.47 +  {
    7.48 +    std::cout << "preflow ..." << std::endl;
    7.49 +    ts.reset();
    7.50 +    max_flow_test.run();
    7.51 +    std::cout << "elapsed time: " << ts << std::endl;
    7.52 +    std::cout << "flow value: "<< max_flow_test.flowValue() << std::endl;
    7.53 +    max_flow_test.minCut(cut);
    7.54 +
    7.55 +    for (EdgeIt e(g); e!=INVALID; ++e) {
    7.56 +      if (cut[g.source(e)] && !cut[g.target(e)] && !flow[e]==cap[e]) 
    7.57 +	std::cout << "Slackness does not hold!" << std::endl;
    7.58 +      if (!cut[g.source(e)] && cut[g.target(e)] && flow[e]>0) 
    7.59 +	std::cout << "Slackness does not hold!" << std::endl;
    7.60 +    }
    7.61 +  }
    7.62 +
    7.63 +//   {
    7.64 +//     std::cout << "preflow ..." << std::endl;
    7.65 +//     FOR_EACH_LOC(Graph::EdgeIt, e, g) flow.set(e, 0);
    7.66 +//     ts.reset();
    7.67 +//     max_flow_test.preflow(Preflow<Graph, int, Graph::EdgeMap<int>, Graph::EdgeMap<int> >::GEN_FLOW);
    7.68 +//     std::cout << "elapsed time: " << ts << std::endl;
    7.69 +//     std::cout << "flow value: "<< max_flow_test.flowValue() << std::endl;
    7.70 +
    7.71 +//     FOR_EACH_LOC(Graph::EdgeIt, e, g) {
    7.72 +//       if (cut[g.source(e)] && !cut[g.target(e)] && !flow[e]==cap[e]) 
    7.73 +// 	std::cout << "Slackness does not hold!" << std::endl;
    7.74 +//       if (!cut[g.source(e)] && cut[g.target(e)] && flow[e]>0) 
    7.75 +// 	std::cout << "Slackness does not hold!" << std::endl;
    7.76 +//     }
    7.77 +//   }
    7.78 +
    7.79 +//   {
    7.80 +//     std::cout << "wrapped preflow ..." << std::endl;
    7.81 +//     FOR_EACH_LOC(Graph::EdgeIt, e, g) flow.set(e, 0);
    7.82 +//     ts.reset();
    7.83 +//     pre_flow_res.run();
    7.84 +//     std::cout << "elapsed time: " << ts << std::endl;
    7.85 +//     std::cout << "flow value: "<< pre_flow_test.flowValue() << std::endl;
    7.86 +//   }
    7.87 +
    7.88 +  {
    7.89 +    std::cout << "physical blocking flow augmentation ..." << std::endl;
    7.90 +    for (EdgeIt e(g); e!=INVALID; ++e) flow.set(e, 0);
    7.91 +    ts.reset();
    7.92 +    int i=0;
    7.93 +    while (augmenting_flow_test.augmentOnBlockingFlow<MutableGraph>()) { ++i; }
    7.94 +    std::cout << "elapsed time: " << ts << std::endl;
    7.95 +    std::cout << "number of augmentation phases: " << i << std::endl; 
    7.96 +    std::cout << "flow value: "<< augmenting_flow_test.flowValue() << std::endl;
    7.97 +
    7.98 +    for (EdgeIt e(g); e!=INVALID; ++e) {
    7.99 +      if (cut[g.source(e)] && !cut[g.target(e)] && !flow[e]==cap[e]) 
   7.100 +	std::cout << "Slackness does not hold!" << std::endl;
   7.101 +      if (!cut[g.source(e)] && cut[g.target(e)] && flow[e]>0) 
   7.102 +	std::cout << "Slackness does not hold!" << std::endl;
   7.103 +    }
   7.104 +  }
   7.105 +
   7.106 +//   {
   7.107 +//     std::cout << "faster physical blocking flow augmentation ..." << std::endl;
   7.108 +//     FOR_EACH_LOC(Graph::EdgeIt, e, g) flow.set(e, 0);
   7.109 +//     ts.reset();
   7.110 +//     int i=0;
   7.111 +//     while (max_flow_test.augmentOnBlockingFlow1<MutableGraph>()) { ++i; }
   7.112 +//     std::cout << "elapsed time: " << ts << std::endl;
   7.113 +//     std::cout << "number of augmentation phases: " << i << std::endl; 
   7.114 +//     std::cout << "flow value: "<< max_flow_test.flowValue() << std::endl;
   7.115 +//   }
   7.116 +
   7.117 +  {
   7.118 +    std::cout << "on-the-fly blocking flow augmentation ..." << std::endl;
   7.119 +    for (EdgeIt e(g); e!=INVALID; ++e) flow.set(e, 0);
   7.120 +    ts.reset();
   7.121 +    int i=0;
   7.122 +    while (augmenting_flow_test.augmentOnBlockingFlow2()) { ++i; }
   7.123 +    std::cout << "elapsed time: " << ts << std::endl;
   7.124 +    std::cout << "number of augmentation phases: " << i << std::endl; 
   7.125 +    std::cout << "flow value: "<< augmenting_flow_test.flowValue() << std::endl;
   7.126 +
   7.127 +    for (EdgeIt e(g); e!=INVALID; ++e) {
   7.128 +      if (cut[g.source(e)] && !cut[g.target(e)] && !flow[e]==cap[e]) 
   7.129 +	std::cout << "Slackness does not hold!" << std::endl;
   7.130 +      if (!cut[g.source(e)] && cut[g.target(e)] && flow[e]>0) 
   7.131 +	std::cout << "Slackness does not hold!" << std::endl;
   7.132 +    }
   7.133 +  }
   7.134 +
   7.135 +//   {
   7.136 +//     std::cout << "on-the-fly shortest path augmentation ..." << std::endl;
   7.137 +//     FOR_EACH_LOC(Graph::EdgeIt, e, g) flow.set(e, 0);
   7.138 +//     ts.reset();
   7.139 +//     int i=0;
   7.140 +//     while (augmenting_flow_test.augmentOnShortestPath()) { ++i; }
   7.141 +//     std::cout << "elapsed time: " << ts << std::endl;
   7.142 +//     std::cout << "number of augmentation phases: " << i << std::endl; 
   7.143 +//     std::cout << "flow value: "<< augmenting_flow_test.flowValue() << std::endl;
   7.144 +
   7.145 +//     FOR_EACH_LOC(Graph::EdgeIt, e, g) {
   7.146 +//       if (cut[g.source(e)] && !cut[g.target(e)] && !flow[e]==cap[e]) 
   7.147 +// 	std::cout << "Slackness does not hold!" << std::endl;
   7.148 +//       if (!cut[g.source(e)] && cut[g.target(e)] && flow[e]>0) 
   7.149 +// 	std::cout << "Slackness does not hold!" << std::endl;
   7.150 +//     }
   7.151 +//   }
   7.152 +
   7.153 +//   {
   7.154 +//     std::cout << "on-the-fly shortest path augmentation ..." << std::endl;
   7.155 +//     FOR_EACH_LOC(Graph::EdgeIt, e, g) flow.set(e, 0);
   7.156 +//     ts.reset();
   7.157 +//     int i=0;
   7.158 +//     while (augmenting_flow_test.augmentOnShortestPath2()) { ++i; }
   7.159 +//     std::cout << "elapsed time: " << ts << std::endl;
   7.160 +//     std::cout << "number of augmentation phases: " << i << std::endl; 
   7.161 +//     std::cout << "flow value: "<< augmenting_flow_test.flowValue() << std::endl;
   7.162 +
   7.163 +//     FOR_EACH_LOC(Graph::EdgeIt, e, g) {
   7.164 +//       if (cut[g.source(e)] && !cut[g.target(e)] && !flow[e]==cap[e]) 
   7.165 +// 	std::cout << "Slackness does not hold!" << std::endl;
   7.166 +//       if (!cut[g.source(e)] && cut[g.target(e)] && flow[e]>0) 
   7.167 +// 	std::cout << "Slackness does not hold!" << std::endl;
   7.168 +//     }
   7.169 +//   }
   7.170 +
   7.171 +  ts.reset();
   7.172 +
   7.173 +  Edge e=g.addEdge(t, s);
   7.174 +  Graph::EdgeMap<int> cost(g, 0);
   7.175 +  cost.set(e, -1);
   7.176 +  cap.set(e, 10000);
   7.177 +  typedef ConstMap<Node, int> Excess;
   7.178 +  Excess excess(0);
   7.179 +  typedef ConstMap<Edge, int> LCap;
   7.180 +  LCap lcap(0);
   7.181 +
   7.182 +  MinCostGenFlow<Graph, int, Excess, LCap> 
   7.183 +    min_cost(g, excess, lcap, cap, flow, cost); 
   7.184 +  min_cost.feasible();
   7.185 +  min_cost.runByLP();
   7.186 +
   7.187 +  std::cout << "elapsed time: " << ts << std::endl;
   7.188 +  std::cout << "flow value: "<< flow[e] << std::endl;
   7.189 +}
     8.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     8.2 +++ b/src/work/athos/lp/max_flow_expression.cc	Tue Mar 22 11:45:47 2005 +0000
     8.3 @@ -0,0 +1,109 @@
     8.4 +// -*- c++ -*-
     8.5 +#include <iostream>
     8.6 +#include <fstream>
     8.7 +
     8.8 +#include <lemon/graph_utils.h>
     8.9 +#include <lemon/smart_graph.h>
    8.10 +#include <lemon/list_graph.h>
    8.11 +#include <lemon/dimacs.h>
    8.12 +#include <lemon/time_measure.h>
    8.13 +#include <lp_solver_base.h>
    8.14 +
    8.15 +using std::cout;
    8.16 +using std::endl;
    8.17 +using namespace lemon;
    8.18 +
    8.19 +template<typename Edge, typename EdgeIndexMap> 
    8.20 +class PrimalMap {
    8.21 +protected:
    8.22 +  LPGLPK* lp;
    8.23 +  EdgeIndexMap* edge_index_map;
    8.24 +public:
    8.25 +  PrimalMap(LPGLPK& _lp, EdgeIndexMap& _edge_index_map) : 
    8.26 +    lp(&_lp), edge_index_map(&_edge_index_map) { }
    8.27 +  double operator[](Edge e) const { 
    8.28 +    return lp->getPrimal((*edge_index_map)[e]);
    8.29 +  }
    8.30 +};
    8.31 +
    8.32 +// Use a DIMACS max flow file as stdin.
    8.33 +// max_flow_expresion < dimacs_max_flow_file
    8.34 +
    8.35 +int main(int, char **) {
    8.36 +
    8.37 +  typedef ListGraph Graph;
    8.38 +  typedef Graph::Node Node;
    8.39 +  typedef Graph::Edge Edge;
    8.40 +  typedef Graph::EdgeIt EdgeIt;
    8.41 +
    8.42 +  Graph g;
    8.43 +  
    8.44 +  Node s, t;
    8.45 +  Graph::EdgeMap<int> cap(g);
    8.46 +  readDimacs(std::cin, g, cap, s, t);
    8.47 +  Timer ts;
    8.48 +  
    8.49 +  typedef LPGLPK LPSolver;
    8.50 +  LPSolver lp;
    8.51 +  lp.setMaximize();
    8.52 +  typedef LPSolver::Col Col;
    8.53 +  typedef LPSolver::Row Row;
    8.54 +  typedef Graph::EdgeMap<Col> EdgeIndexMap;
    8.55 +  typedef Graph::NodeMap<Row> NodeIndexMap;
    8.56 +  EdgeIndexMap edge_index_map(g);
    8.57 +  NodeIndexMap node_index_map(g);
    8.58 +  PrimalMap<Edge, EdgeIndexMap> flow(lp, edge_index_map);
    8.59 +
    8.60 +  // nonnegativity of flow and capacity function
    8.61 +  for (Graph::EdgeIt e(g); e!=INVALID; ++e) {
    8.62 +    Col col=lp.addCol();
    8.63 +    edge_index_map.set(e, col);
    8.64 +    // interesting property in GLPK:
    8.65 +    // if you change the order of the following two lines, the 
    8.66 +    // two runs of GLPK are extremely different
    8.67 +      lp.setColLowerBound(col, 0);
    8.68 +      lp.setColUpperBound(col, cap[e]);
    8.69 +  }
    8.70 +  
    8.71 +  for (Graph::NodeIt n(g); n!=INVALID; ++n) {
    8.72 +    LPSolver::Expression expr;
    8.73 +    for (Graph::OutEdgeIt e(g, n); e!=INVALID; ++e)
    8.74 +      expr+=edge_index_map[e];
    8.75 +    for (Graph::InEdgeIt e(g, n); e!=INVALID; ++e)
    8.76 +      expr-=edge_index_map[e];
    8.77 +    // cost function
    8.78 +    if (n==s) {
    8.79 +      lp.setObjCoeffs(expr);      
    8.80 +    }
    8.81 +    // flow conservation constraints
    8.82 +    if ((n!=s) && (n!=t)) {
    8.83 +      node_index_map.set(n, lp.addRow(expr == 0.0));
    8.84 +    }
    8.85 +  }
    8.86 +  lp.solveSimplex();
    8.87 +  cout << "elapsed time: " << ts << endl;
    8.88 +//   cout << "rows:" << endl;
    8.89 +//   for (
    8.90 +//        LPSolver::Rows::ClassIt i(lp.row_iter_map, 0);
    8.91 +//        i!=INVALID;
    8.92 +//        ++i) { 
    8.93 +//     cout << i << " ";
    8.94 +//   }
    8.95 +//   cout << endl;
    8.96 +//   cout << "cols:" << endl;
    8.97 +//   for (
    8.98 +//        LPSolver::Cols::ClassIt i(lp.col_iter_map, 0);
    8.99 +//        i!=INVALID;
   8.100 +//        ++i) { 
   8.101 +//     cout << i << " ";
   8.102 +//   }
   8.103 +//   cout << endl;
   8.104 +  lp.setMIP();
   8.105 +  cout << "elapsed time: " << ts << endl;
   8.106 +  for (LPSolver::Cols::ClassIt it(lp.col_iter_map ,1); it!=INVALID; ++it) {
   8.107 +    lp.setColInt(it);
   8.108 +  }
   8.109 +  cout << "elapsed time: " << ts << endl;
   8.110 +  lp.solveBandB();
   8.111 +  cout << "elapsed time: " << ts << endl;
   8.112 +}
     9.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     9.2 +++ b/src/work/athos/lp/min_cost_gen_flow.h	Tue Mar 22 11:45:47 2005 +0000
     9.3 @@ -0,0 +1,268 @@
     9.4 +// -*- c++ -*-
     9.5 +#ifndef LEMON_MIN_COST_GEN_FLOW_H
     9.6 +#define LEMON_MIN_COST_GEN_FLOW_H
     9.7 +#include <iostream>
     9.8 +//#include <fstream>
     9.9 +
    9.10 +#include <lemon/smart_graph.h>
    9.11 +#include <lemon/list_graph.h>
    9.12 +//#include <lemon/dimacs.h>
    9.13 +//#include <lemon/time_measure.h>
    9.14 +//#include <graph_wrapper.h>
    9.15 +#include <lemon/preflow.h>
    9.16 +#include <lemon/min_cost_flow.h>
    9.17 +//#include <augmenting_flow.h>
    9.18 +//#include <preflow_res.h>
    9.19 +#include <work/marci/merge_node_graph_wrapper.h>
    9.20 +#include <work/marci/lp/lp_solver_wrapper_3.h>
    9.21 +
    9.22 +namespace lemon {
    9.23 +
    9.24 +  template<typename Edge, typename EdgeIndexMap> 
    9.25 +  class PrimalMap {
    9.26 +  protected:
    9.27 +    LPGLPK* lp;
    9.28 +    EdgeIndexMap* edge_index_map;
    9.29 +  public:
    9.30 +    PrimalMap(LPGLPK& _lp, EdgeIndexMap& _edge_index_map) : 
    9.31 +      lp(&_lp), edge_index_map(&_edge_index_map) { }
    9.32 +    double operator[](Edge e) const { 
    9.33 +      return lp->getPrimal((*edge_index_map)[e]);
    9.34 +    }
    9.35 +  };
    9.36 +
    9.37 +  // excess: rho-delta egyelore csak =0-ra.
    9.38 +  template <typename Graph, typename Num,
    9.39 +	    typename Excess=typename Graph::template NodeMap<Num>, 
    9.40 +	    typename LCapMap=typename Graph::template EdgeMap<Num>,
    9.41 +	    typename CapMap=typename Graph::template EdgeMap<Num>,
    9.42 +            typename FlowMap=typename Graph::template EdgeMap<Num>,
    9.43 +	    typename CostMap=typename Graph::template EdgeMap<Num> >
    9.44 +  class MinCostGenFlow {
    9.45 +  protected:
    9.46 +    const Graph& g;
    9.47 +    const Excess& excess;
    9.48 +    const LCapMap& lcapacity;
    9.49 +    const CapMap& capacity;
    9.50 +    FlowMap& flow;
    9.51 +    const CostMap& cost;
    9.52 +  public:
    9.53 +    MinCostGenFlow(const Graph& _g, const Excess& _excess, 
    9.54 +		   const LCapMap& _lcapacity, const CapMap& _capacity, 
    9.55 +		   FlowMap& _flow, 
    9.56 +		   const CostMap& _cost) :
    9.57 +      g(_g), excess(_excess), lcapacity(_lcapacity),
    9.58 +      capacity(_capacity), flow(_flow), cost(_cost) { }
    9.59 +    bool feasible() {
    9.60 +      //      std::cout << "making new vertices..." << std::endl; 
    9.61 +      typedef ListGraph Graph2;
    9.62 +      Graph2 g2;
    9.63 +      typedef MergeEdgeGraphWrapper<const Graph, Graph2> GW;
    9.64 +      //      std::cout << "merging..." << std::endl; 
    9.65 +      GW gw(g, g2);
    9.66 +      typename GW::Node s(INVALID, g2.addNode(), true);
    9.67 +      typename GW::Node t(INVALID, g2.addNode(), true);
    9.68 +      typedef SmartGraph Graph3;
    9.69 +      //      std::cout << "making extender graph..." << std::endl; 
    9.70 +      typedef NewEdgeSetGraphWrapper2<GW, Graph3> GWW;
    9.71 +//       {
    9.72 +// 	checkConcept<StaticGraph, GWW>();   
    9.73 +//       }
    9.74 +      GWW gww(gw);
    9.75 +      typedef AugmentingGraphWrapper<GW, GWW> GWWW;
    9.76 +      GWWW gwww(gw, gww);
    9.77 +
    9.78 +      //      std::cout << "making new edges..." << std::endl; 
    9.79 +      typename GWWW::template EdgeMap<Num> translated_cap(gwww);
    9.80 +
    9.81 +      for (typename GW::EdgeIt e(gw); e!=INVALID; ++e) {
    9.82 +	translated_cap.set(typename GWWW::Edge(e,INVALID,false), 
    9.83 +			   capacity[e]-lcapacity[e]);
    9.84 +	//	cout << "t_cap " << gw.id(e) << " " 
    9.85 +	//	     << translated_cap[typename GWWW::Edge(e,INVALID,false)] << endl;
    9.86 +      }
    9.87 +
    9.88 +      Num expected=0;
    9.89 +
    9.90 +      //      std::cout << "making new edges 2..." << std::endl; 
    9.91 +      for (typename Graph::NodeIt n(g); n!=INVALID; ++n) {
    9.92 +	Num a=0;
    9.93 +	for (typename Graph::InEdgeIt e(g, n); e!=INVALID; ++e)
    9.94 +	  a+=lcapacity[e];
    9.95 +	for (typename Graph::OutEdgeIt e(g, n); e!=INVALID; ++e) 
    9.96 +	  a-=lcapacity[e];
    9.97 +	if (excess[n]>a) {
    9.98 +	  typename GWW::Edge e=
    9.99 +	    gww.addEdge(typename GW::Node(n,INVALID,false), t);
   9.100 +	  translated_cap.set(typename GWWW::Edge(INVALID, e, true), 
   9.101 +			     excess[n]-a);
   9.102 +	  //	  std::cout << g.id(n) << "->t " << excess[n]-a << std::endl;
   9.103 +	}
   9.104 +	if (excess[n]<a) {
   9.105 +	  typename GWW::Edge e=
   9.106 +	    gww.addEdge(s, typename GW::Node(n,INVALID,false));
   9.107 +	  translated_cap.set(typename GWWW::Edge(INVALID, e, true), 
   9.108 +			     a-excess[n]);
   9.109 +	  expected+=a-excess[n];
   9.110 +	  //	  std::cout << "s->" << g.id(n) << " "<< a-excess[n] <<std:: endl;
   9.111 +	}
   9.112 +      }
   9.113 +
   9.114 +      //      std::cout << "preflow..." << std::endl; 
   9.115 +      typename GWWW::template EdgeMap<Num> translated_flow(gwww, 0);
   9.116 +      Preflow<GWWW, Num> preflow(gwww, s, t, 
   9.117 +				 translated_cap, translated_flow);
   9.118 +      preflow.run();
   9.119 +      //      std::cout << "fv: " << preflow.flowValue() << std::endl; 
   9.120 +      //      std::cout << "expected: " << expected << std::endl; 
   9.121 +
   9.122 +      for (typename Graph::EdgeIt e(g); e!=INVALID; ++e) {
   9.123 +	typename GW::Edge ew(e, INVALID, false);
   9.124 +	typename GWWW::Edge ewww(ew, INVALID, false);
   9.125 +	flow.set(e, translated_flow[ewww]+lcapacity[e]);
   9.126 +      }
   9.127 +      return (preflow.flowValue()>=expected);
   9.128 +    }
   9.129 +    // for nonnegative costs
   9.130 +    bool run() {
   9.131 +      //      std::cout << "making new vertices..." << std::endl; 
   9.132 +      typedef ListGraph Graph2;
   9.133 +      Graph2 g2;
   9.134 +      typedef MergeEdgeGraphWrapper<const Graph, Graph2> GW;
   9.135 +      //      std::cout << "merging..." << std::endl; 
   9.136 +      GW gw(g, g2);
   9.137 +      typename GW::Node s(INVALID, g2.addNode(), true);
   9.138 +      typename GW::Node t(INVALID, g2.addNode(), true);
   9.139 +      typedef SmartGraph Graph3;
   9.140 +      //      std::cout << "making extender graph..." << std::endl; 
   9.141 +      typedef NewEdgeSetGraphWrapper2<GW, Graph3> GWW;
   9.142 +//       {
   9.143 +// 	checkConcept<StaticGraph, GWW>();   
   9.144 +//       }
   9.145 +      GWW gww(gw);
   9.146 +      typedef AugmentingGraphWrapper<GW, GWW> GWWW;
   9.147 +      GWWW gwww(gw, gww);
   9.148 +
   9.149 +      //      std::cout << "making new edges..." << std::endl; 
   9.150 +      typename GWWW::template EdgeMap<Num> translated_cap(gwww);
   9.151 +
   9.152 +      for (typename Graph::EdgeIt e(g); e!=INVALID; ++e) {
   9.153 +	typename GW::Edge ew(e, INVALID, false);
   9.154 +	typename GWWW::Edge ewww(ew, INVALID, false);
   9.155 +	translated_cap.set(ewww, capacity[e]-lcapacity[e]);
   9.156 +	//	cout << "t_cap " << g.id(e) << " " 
   9.157 +	//	     << translated_cap[ewww] << endl;
   9.158 +      }
   9.159 +
   9.160 +      Num expected=0;
   9.161 +
   9.162 +      //      std::cout << "making new edges 2..." << std::endl; 
   9.163 +      for (typename Graph::NodeIt n(g); n!=INVALID; ++n) {
   9.164 +	//	std::cout << "node: " << g.id(n) << std::endl;
   9.165 +	Num a=0;
   9.166 +	for (typename Graph::InEdgeIt e(g, n); e!=INVALID; ++e) {
   9.167 +	  a+=lcapacity[e];
   9.168 +	  //	  std::cout << "bee: " << g.id(e) << " " << lcapacity[e] << std::endl;
   9.169 +	}
   9.170 +	for (typename Graph::OutEdgeIt e(g, n); e!=INVALID; ++e) {
   9.171 +	  a-=lcapacity[e];
   9.172 +	  //	  std::cout << "kie: " << g.id(e) << " " << lcapacity[e] << std::endl;
   9.173 +	}
   9.174 +	//	std::cout << "excess " << g.id(n) << ": " << a << std::endl;
   9.175 +	if (0>a) {
   9.176 +	  typename GWW::Edge e=
   9.177 +	    gww.addEdge(typename GW::Node(n,INVALID,false), t);
   9.178 +	  translated_cap.set(typename GWWW::Edge(INVALID, e, true), 
   9.179 +			     -a);
   9.180 +	  //	  std::cout << g.id(n) << "->t " << -a << std::endl;
   9.181 +	}
   9.182 +	if (0<a) {
   9.183 +	  typename GWW::Edge e=
   9.184 +	    gww.addEdge(s, typename GW::Node(n,INVALID,false));
   9.185 +	  translated_cap.set(typename GWWW::Edge(INVALID, e, true), 
   9.186 +			     a);
   9.187 +	  expected+=a;
   9.188 +	  //	  std::cout << "s->" << g.id(n) << " "<< a <<std:: endl;
   9.189 +	}
   9.190 +      }
   9.191 +
   9.192 +      //      std::cout << "preflow..." << std::endl; 
   9.193 +      typename GWWW::template EdgeMap<Num> translated_cost(gwww, 0);
   9.194 +      for (typename Graph::EdgeIt e(g); e!=INVALID; ++e) {
   9.195 +	translated_cost.set(typename GWWW::Edge(
   9.196 +        typename GW::Edge(e, INVALID, false), INVALID, false), cost[e]);
   9.197 +      }
   9.198 +      //      typename GWWW::template EdgeMap<Num> translated_flow(gwww, 0);
   9.199 +      MinCostFlow<GWWW, typename GWWW::template EdgeMap<Num>, 
   9.200 +      typename GWWW::template EdgeMap<Num> > 
   9.201 +      min_cost_flow(gwww, translated_cost, translated_cap, 
   9.202 +		    s, t);
   9.203 +      while (min_cost_flow.augment()) { }
   9.204 +      std::cout << "fv: " << min_cost_flow.flowValue() << std::endl; 
   9.205 +      std::cout << "expected: " << expected << std::endl; 
   9.206 +
   9.207 +      for (typename Graph::EdgeIt e(g); e!=INVALID; ++e) {
   9.208 +	typename GW::Edge ew(e, INVALID, false);
   9.209 +	typename GWWW::Edge ewww(ew, INVALID, false);
   9.210 +	//	std::cout << g.id(e) << " " << flow[e] << std::endl;
   9.211 +	flow.set(e, lcapacity[e]+
   9.212 +		 min_cost_flow.getFlow()[ewww]);
   9.213 +      }
   9.214 +      return (min_cost_flow.flowValue()>=expected);
   9.215 +    }
   9.216 +    void runByLP() {
   9.217 +      typedef LPGLPK LPSolver;
   9.218 +      LPSolver lp;
   9.219 +      lp.setMinimize();
   9.220 +      typedef LPSolver::ColIt ColIt;
   9.221 +      typedef LPSolver::RowIt RowIt;
   9.222 +      typedef typename Graph::template EdgeMap<ColIt> EdgeIndexMap;
   9.223 +      EdgeIndexMap edge_index_map(g);
   9.224 +      PrimalMap<typename Graph::Edge, EdgeIndexMap> lp_flow(lp, edge_index_map);
   9.225 +      for (typename Graph::EdgeIt e(g); e!=INVALID; ++e) {
   9.226 +	ColIt col_it=lp.addCol();
   9.227 +	edge_index_map.set(e, col_it);
   9.228 +	if (lcapacity[e]==capacity[e])
   9.229 +	  lp.setColBounds(col_it, LPSolver::FIXED, lcapacity[e], capacity[e]);
   9.230 +	else 
   9.231 +	  lp.setColBounds(col_it, LPSolver::DOUBLE, lcapacity[e], capacity[e]);
   9.232 +	lp.setObjCoef(col_it, cost[e]);
   9.233 +      }
   9.234 +      LPSolver::ColIt col_it;
   9.235 +      for (lp.col_iter_map.first(col_it, lp.VALID_CLASS); 
   9.236 +	   lp.col_iter_map.valid(col_it); 
   9.237 +	   lp.col_iter_map.next(col_it)) {
   9.238 +//	std::cout << "ize " << lp.col_iter_map[col_it] << std::endl;
   9.239 +      }
   9.240 +      for (typename Graph::NodeIt n(g); n!=INVALID; ++n) {
   9.241 +	typename Graph::template EdgeMap<Num> coeffs(g, 0);
   9.242 +	for (typename Graph::InEdgeIt e(g, n); e!=INVALID; ++e)
   9.243 +	coeffs.set(e, coeffs[e]+1);
   9.244 +	for (typename Graph::OutEdgeIt e(g, n); e!=INVALID; ++e) 
   9.245 +	coeffs.set(e, coeffs[e]-1);
   9.246 +	RowIt row_it=lp.addRow();
   9.247 +	typename std::vector< std::pair<ColIt, double> > row;
   9.248 +	//std::cout << "node:" <<g.id(n)<<std::endl;
   9.249 +	for (typename Graph::EdgeIt e(g); e!=INVALID; ++e) {
   9.250 +	  if (coeffs[e]!=0) {
   9.251 +	    //std::cout << " edge:" <<g.id(e)<<" "<<coeffs[e];
   9.252 +	    row.push_back(std::make_pair(edge_index_map[e], coeffs[e]));
   9.253 +	  }
   9.254 +	}
   9.255 +	//std::cout << std::endl;
   9.256 +	//std::cout << " " << g.id(n) << " " << row.size() << std::endl;
   9.257 +	lp.setRowCoeffs(row_it, row.begin(), row.end());
   9.258 +	lp.setRowBounds(row_it, LPSolver::FIXED, 0.0, 0.0);
   9.259 +      }
   9.260 +      lp.solveSimplex();
   9.261 +      //std::cout << lp.colNum() << std::endl;
   9.262 +      //std::cout << lp.rowNum() << std::endl;
   9.263 +      //std::cout << "flow value: "<< lp.getObjVal() << std::endl;
   9.264 +      for (typename Graph::EdgeIt e(g); e!=INVALID; ++e) 
   9.265 +      flow.set(e, lp_flow[e]);
   9.266 +    }
   9.267 +  };
   9.268 +
   9.269 +} // namespace lemon
   9.270 +
   9.271 +#endif //LEMON_MIN_COST_GEN_FLOW_H