src/work/marci/lp/max_flow_expression.cc
author marci
Thu, 10 Feb 2005 18:53:30 +0000
changeset 1144 1cfabf245433
parent 1143 4fb22cfa5759
child 1152 1765ff9fefa1
permissions -rw-r--r--
trying to add constraints of kind 1 <= x[2]+x[3] <= 4
marci@1104
     1
// -*- c++ -*-
marci@1104
     2
#include <iostream>
marci@1104
     3
#include <fstream>
marci@1104
     4
marci@1143
     5
#include <lemon/graph_utils.h>
marci@1104
     6
#include <lemon/smart_graph.h>
marci@1104
     7
#include <lemon/list_graph.h>
marci@1104
     8
#include <lemon/dimacs.h>
marci@1104
     9
#include <lemon/time_measure.h>
marci@1111
    10
#include <lp_solver_base.h>
marci@1104
    11
marci@1104
    12
using std::cout;
marci@1104
    13
using std::endl;
marci@1104
    14
using namespace lemon;
marci@1104
    15
marci@1104
    16
template<typename Edge, typename EdgeIndexMap> 
marci@1104
    17
class PrimalMap {
marci@1104
    18
protected:
marci@1104
    19
  LPGLPK* lp;
marci@1104
    20
  EdgeIndexMap* edge_index_map;
marci@1104
    21
public:
marci@1104
    22
  PrimalMap(LPGLPK& _lp, EdgeIndexMap& _edge_index_map) : 
marci@1104
    23
    lp(&_lp), edge_index_map(&_edge_index_map) { }
marci@1104
    24
  double operator[](Edge e) const { 
marci@1104
    25
    return lp->getPrimal((*edge_index_map)[e]);
marci@1104
    26
  }
marci@1104
    27
};
marci@1104
    28
marci@1104
    29
// Use a DIMACS max flow file as stdin.
marci@1104
    30
// max_flow_expresion < dimacs_max_flow_file
marci@1104
    31
marci@1104
    32
int main(int, char **) {
marci@1104
    33
marci@1104
    34
  typedef ListGraph Graph;
marci@1104
    35
  typedef Graph::Node Node;
marci@1104
    36
  typedef Graph::Edge Edge;
marci@1104
    37
  typedef Graph::EdgeIt EdgeIt;
marci@1104
    38
marci@1104
    39
  Graph g;
marci@1104
    40
  
marci@1104
    41
  Node s, t;
marci@1104
    42
  Graph::EdgeMap<int> cap(g);
marci@1104
    43
  readDimacs(std::cin, g, cap, s, t);
marci@1104
    44
  Timer ts;
marci@1104
    45
  
marci@1104
    46
  typedef LPGLPK LPSolver;
marci@1104
    47
  LPSolver lp;
marci@1104
    48
  lp.setMaximize();
marci@1144
    49
  typedef LPSolver::Col Col;
marci@1144
    50
  typedef LPSolver::Row Row;
marci@1144
    51
  typedef Graph::EdgeMap<Col> EdgeIndexMap;
marci@1144
    52
  typedef Graph::NodeMap<Row> NodeIndexMap;
marci@1104
    53
  EdgeIndexMap edge_index_map(g);
marci@1143
    54
  NodeIndexMap node_index_map(g);
marci@1110
    55
  PrimalMap<Edge, EdgeIndexMap> flow(lp, edge_index_map);
marci@1104
    56
marci@1111
    57
  // nonnegativity of flow and capacity function
marci@1104
    58
  for (Graph::EdgeIt e(g); e!=INVALID; ++e) {
marci@1144
    59
    Col col=lp.addCol();
marci@1144
    60
    edge_index_map.set(e, col);
marci@1110
    61
    // interesting property in GLPK:
marci@1110
    62
    // if you change the order of the following two lines, the 
marci@1110
    63
    // two runs of GLPK are extremely different
marci@1144
    64
      lp.setColLowerBound(col, 0);
marci@1144
    65
      lp.setColUpperBound(col, cap[e]);
marci@1104
    66
  }
marci@1104
    67
  
marci@1104
    68
  for (Graph::NodeIt n(g); n!=INVALID; ++n) {
marci@1104
    69
    LPSolver::Expression expr;
marci@1104
    70
    for (Graph::OutEdgeIt e(g, n); e!=INVALID; ++e)
marci@1104
    71
      expr+=edge_index_map[e];
marci@1104
    72
    for (Graph::InEdgeIt e(g, n); e!=INVALID; ++e)
marci@1104
    73
      expr-=edge_index_map[e];
marci@1104
    74
    // cost function
marci@1104
    75
    if (n==s) {
marci@1104
    76
      lp.setObjCoeffs(expr);      
marci@1104
    77
    }
marci@1111
    78
    // flow conservation constraints
marci@1104
    79
    if ((n!=s) && (n!=t)) {
marci@1144
    80
      node_index_map.set(n, lp.addRow(expr == 0.0));
marci@1104
    81
    }
marci@1104
    82
  }
marci@1104
    83
  lp.solveSimplex();
marci@1110
    84
  cout << "elapsed time: " << ts << endl;
marci@1104
    85
}